diff --git a/backup/moodle2/backup_certificate_activity_task.class.php b/backup/moodle2/backup_certificate_activity_task.class.php index 07b8173..a8978e8 100644 --- a/backup/moodle2/backup_certificate_activity_task.class.php +++ b/backup/moodle2/backup_certificate_activity_task.class.php @@ -16,7 +16,7 @@ // along with Moodle. If not, see . /** - * @package moodlecore + * @package mod_certificate * @subpackage backup-moodle2 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later diff --git a/backup/moodle2/backup_certificate_settingslib.php b/backup/moodle2/backup_certificate_settingslib.php index 8846b6d..e3e0b76 100644 --- a/backup/moodle2/backup_certificate_settingslib.php +++ b/backup/moodle2/backup_certificate_settingslib.php @@ -16,7 +16,7 @@ // along with Moodle. If not, see . /** - * @package moodlecore + * @package mod_certificate * @subpackage backup-moodle2 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later diff --git a/backup/moodle2/backup_certificate_stepslib.php b/backup/moodle2/backup_certificate_stepslib.php index 143f2e4..52bd96d 100644 --- a/backup/moodle2/backup_certificate_stepslib.php +++ b/backup/moodle2/backup_certificate_stepslib.php @@ -16,7 +16,7 @@ // along with Moodle. If not, see . /** - * @package moodlecore + * @package mod_certificate * @subpackage backup-moodle2 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later diff --git a/backup/moodle2/restore_certificate_activity_task.class.php b/backup/moodle2/restore_certificate_activity_task.class.php index 2f88c0a..38a320d 100644 --- a/backup/moodle2/restore_certificate_activity_task.class.php +++ b/backup/moodle2/restore_certificate_activity_task.class.php @@ -16,7 +16,7 @@ // along with Moodle. If not, see . /** - * @package moodlecore + * @package mod_certificate * @subpackage backup-moodle2 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later diff --git a/backup/moodle2/restore_certificate_stepslib.php b/backup/moodle2/restore_certificate_stepslib.php index 5cf3bdf..654e951 100644 --- a/backup/moodle2/restore_certificate_stepslib.php +++ b/backup/moodle2/restore_certificate_stepslib.php @@ -16,7 +16,7 @@ // along with Moodle. If not, see . /** - * @package moodlecore + * @package mod_certificate * @subpackage backup-moodle2 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later @@ -69,6 +69,9 @@ class restore_certificate_activity_structure_step extends restore_activity_struc $data->certificateid = $this->get_new_parentid('certificate'); $data->timecreated = $this->apply_date_offset($data->timecreated); + if ($data->userid > 0) { + $data->userid = $this->get_mappingid('user', $data->userid); + } $newitemid = $DB->insert_record('certificate_issues', $data); $this->set_mapping('certificate_issue', $oldid, $newitemid); diff --git a/classes/admin_setting_font.php b/classes/admin_setting_font.php new file mode 100644 index 0000000..ac1edd2 --- /dev/null +++ b/classes/admin_setting_font.php @@ -0,0 +1,72 @@ +. + +/** + * Certificate module data generator. + * + * @package mod_certificate + * @copyright 2014 Totara Learning Solutions Ltd {@link http://www.totaralms.com/} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @author Petr Skoda + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->libdir.'/adminlib.php'); + +class mod_certificate_admin_setting_font extends admin_setting_configselect { + /** + * Constructor + * @param string $name unique ascii name, either 'mysetting' for settings that in config, or 'myplugin/mysetting' for ones in config_plugins. + * @param string $visiblename localised + * @param string $description long localised info + * @param string|int $defaultsetting + */ + public function __construct($name, $visiblename, $description, $defaultsetting) { + parent::__construct($name, $visiblename, $description, $defaultsetting, null); + } + /** + * Lazy load the font options. + * + * @return bool true if loaded, false if error + */ + public function load_choices() { + global $CFG; + + if (is_array($this->choices)) { + return true; + } + + require_once("$CFG->libdir/pdflib.php"); + + $doc = new pdf(); + + if (method_exists($doc, 'get_font_families')) { + $this->choices = array(); + $fontfamilies = $doc->get_font_families(); + foreach ($fontfamilies as $family => $fonts) { + $this->choices[$family] = $family; + } + + } else { + $this->choices = array( + 'freeserif' => 'freeserif', + 'freesans' => 'freesans', + ); + } + + return true; + } +} diff --git a/classes/admin_setting_upload.php b/classes/admin_setting_upload.php new file mode 100644 index 0000000..acab90c --- /dev/null +++ b/classes/admin_setting_upload.php @@ -0,0 +1,46 @@ +. + +/** + * Creates an upload form on the settings page + * + * @package mod_certificate + * @copyright Michael Avelar + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->libdir.'/adminlib.php'); + +/** + * Class extends admin setting class to allow/process an uploaded file + **/ +class mod_certificate_admin_setting_upload extends admin_setting_configtext { + public function __construct($name, $visiblename, $description, $defaultsetting) { + parent::__construct($name, $visiblename, $description, $defaultsetting, PARAM_RAW, 50); + } + + function output_html($data, $query='') { + // Create a dummy var for this field. + $this->config_write($this->name, ''); + + return format_admin_setting($this, $this->visiblename, + html_writer::link(new moodle_url('/mod/certificate/upload_image.php'), get_string('upload')), + $this->description, true, '', null, $query); + } +} diff --git a/classes/event/course_module_instance_list_viewed.php b/classes/event/course_module_instance_list_viewed.php new file mode 100644 index 0000000..5e338a4 --- /dev/null +++ b/classes/event/course_module_instance_list_viewed.php @@ -0,0 +1,32 @@ +. + +/** + * This page lists all the instances of certificate in a particular course + * + * @package mod + * @subpackage certificate + * @copyright Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_certificate\event; + +defined('MOODLE_INTERNAL') || die(); + +class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed { +} diff --git a/classes/event/course_module_viewed.php b/classes/event/course_module_viewed.php new file mode 100644 index 0000000..bc9d15c --- /dev/null +++ b/classes/event/course_module_viewed.php @@ -0,0 +1,36 @@ +. + +/** + * This page lists all the instances of certificate in a particular course + * + * @package mod + * @subpackage certificate + * @copyright Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_certificate\event; + +defined('MOODLE_INTERNAL') || die(); + +class course_module_viewed extends \core\event\course_module_viewed { + protected function init() { + $this->data['objecttable'] = 'certificate'; + parent::init(); + } +} diff --git a/classes/external.php b/classes/external.php new file mode 100644 index 0000000..f2ad454 --- /dev/null +++ b/classes/external.php @@ -0,0 +1,455 @@ +. + +/** + * Certificate module external API + * + * @package mod_certificate + * @category external + * @copyright 2016 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die; + +require_once($CFG->libdir . '/externallib.php'); +require_once($CFG->dirroot . '/mod/certificate/locallib.php'); + +/** + * Certificate module external functions + * + * @package mod_certificate + * @category external + * @copyright 2015 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class mod_certificate_external extends external_api { + + /** + * Describes the parameters for get_certificates_by_courses. + * + * @return external_function_parameters + */ + public static function get_certificates_by_courses_parameters() { + return new external_function_parameters ( + array( + 'courseids' => new external_multiple_structure( + new external_value(PARAM_INT, 'course id'), 'Array of course ids', VALUE_DEFAULT, array() + ), + ) + ); + } + + /** + * Returns a list of certificates in a provided list of courses, + * if no list is provided all certificates that the user can view will be returned. + * + * @param array $courseids the course ids + * @return array the certificate details + */ + public static function get_certificates_by_courses($courseids = array()) { + global $CFG; + + $returnedcertificates = array(); + $warnings = array(); + + $params = self::validate_parameters(self::get_certificates_by_courses_parameters(), array('courseids' => $courseids)); + + if (empty($params['courseids'])) { + $params['courseids'] = array_keys(enrol_get_my_courses()); + } + + // Ensure there are courseids to loop through. + if (!empty($params['courseids'])) { + + list($courses, $warnings) = external_util::validate_courses($params['courseids']); + + // Get the certificates in this course, this function checks users visibility permissions. + // We can avoid then additional validate_context calls. + $certificates = get_all_instances_in_courses("certificate", $courses); + + foreach ($certificates as $certificate) { + + $context = context_module::instance($certificate->coursemodule); + + // Entry to return. + $module = array(); + + // First, we return information that any user can see in (or can deduce from) the web interface. + $module['id'] = $certificate->id; + $module['coursemodule'] = $certificate->coursemodule; + $module['course'] = $certificate->course; + $module['name'] = external_format_string($certificate->name, $context->id); + + $viewablefields = []; + if (has_capability('mod/certificate:view', $context)) { + list($module['intro'], $module['introformat']) = + external_format_text($certificate->intro, $certificate->introformat, $context->id, + 'mod_certificate', 'intro', $certificate->id); + + // Check certificate requeriments for current user. + $viewablefields[] = 'requiredtime'; + $module['requiredtimenotmet'] = 0; + if ($certificate->requiredtime && !has_capability('mod/certificate:manage', $context)) { + if (certificate_get_course_time($certificate->course) < ($certificate->requiredtime * 60)) { + $module['requiredtimenotmet'] = 1; + } + } + } + + // Check additional permissions for returning optional private settings. + if (has_capability('moodle/course:manageactivities', $context)) { + + $additionalfields = array('emailteachers', 'emailothers', 'savecert', + 'reportcert', 'delivery', 'certificatetype', 'orientation', 'borderstyle', 'bordercolor', + 'printwmark', 'printdate', 'datefmt', 'printnumber', 'printgrade', 'gradefmt', 'printoutcome', + 'printhours', 'printteacher', 'customtext', 'printsignature', 'printseal', 'timecreated', 'timemodified', + 'section', 'visible', 'groupmode', 'groupingid'); + $viewablefields = array_merge($viewablefields, $additionalfields); + + } + + foreach ($viewablefields as $field) { + $module[$field] = $certificate->{$field}; + } + + $returnedcertificates[] = $module; + } + } + + $result = array(); + $result['certificates'] = $returnedcertificates; + $result['warnings'] = $warnings; + return $result; + } + + /** + * Describes the get_certificates_by_courses return value. + * + * @return external_single_structure + */ + public static function get_certificates_by_courses_returns() { + + return new external_single_structure( + array( + 'certificates' => new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'Certificate id'), + 'coursemodule' => new external_value(PARAM_INT, 'Course module id'), + 'course' => new external_value(PARAM_INT, 'Course id'), + 'name' => new external_value(PARAM_RAW, 'Certificate name'), + 'intro' => new external_value(PARAM_RAW, 'The Certificate intro', VALUE_OPTIONAL), + 'introformat' => new external_format_value('intro', VALUE_OPTIONAL), + 'requiredtimenotmet' => new external_value(PARAM_INT, 'Whether the time req is met', VALUE_OPTIONAL), + 'emailteachers' => new external_value(PARAM_INT, 'Email teachers?', VALUE_OPTIONAL), + 'emailothers' => new external_value(PARAM_RAW, 'Email others?', VALUE_OPTIONAL), + 'savecert' => new external_value(PARAM_INT, 'Save certificate?', VALUE_OPTIONAL), + 'reportcert' => new external_value(PARAM_INT, 'Report certificate?', VALUE_OPTIONAL), + 'delivery' => new external_value(PARAM_INT, 'Delivery options', VALUE_OPTIONAL), + 'requiredtime' => new external_value(PARAM_INT, 'Required time', VALUE_OPTIONAL), + 'certificatetype' => new external_value(PARAM_RAW, 'Type', VALUE_OPTIONAL), + 'orientation' => new external_value(PARAM_ALPHANUM, 'Orientation', VALUE_OPTIONAL), + 'borderstyle' => new external_value(PARAM_RAW, 'Border style', VALUE_OPTIONAL), + 'bordercolor' => new external_value(PARAM_RAW, 'Border color', VALUE_OPTIONAL), + 'printwmark' => new external_value(PARAM_RAW, 'Print water mark?', VALUE_OPTIONAL), + 'printdate' => new external_value(PARAM_RAW, 'Print date?', VALUE_OPTIONAL), + 'datefmt' => new external_value(PARAM_INT, 'Date format', VALUE_OPTIONAL), + 'printnumber' => new external_value(PARAM_INT, 'Print number?', VALUE_OPTIONAL), + 'printgrade' => new external_value(PARAM_INT, 'Print grade?', VALUE_OPTIONAL), + 'gradefmt' => new external_value(PARAM_INT, 'Grade format', VALUE_OPTIONAL), + 'printoutcome' => new external_value(PARAM_INT, 'Print outcome?', VALUE_OPTIONAL), + 'printhours' => new external_value(PARAM_TEXT, 'Print hours?', VALUE_OPTIONAL), + 'printteacher' => new external_value(PARAM_INT, 'Print teacher?', VALUE_OPTIONAL), + 'customtext' => new external_value(PARAM_RAW, 'Custom text', VALUE_OPTIONAL), + 'printsignature' => new external_value(PARAM_RAW, 'Print signature?', VALUE_OPTIONAL), + 'printseal' => new external_value(PARAM_RAW, 'Print seal?', VALUE_OPTIONAL), + 'timecreated' => new external_value(PARAM_INT, 'Time created', VALUE_OPTIONAL), + 'timemodified' => new external_value(PARAM_INT, 'Time modified', VALUE_OPTIONAL), + 'section' => new external_value(PARAM_INT, 'course section id', VALUE_OPTIONAL), + 'visible' => new external_value(PARAM_INT, 'visible', VALUE_OPTIONAL), + 'groupmode' => new external_value(PARAM_INT, 'group mode', VALUE_OPTIONAL), + 'groupingid' => new external_value(PARAM_INT, 'group id', VALUE_OPTIONAL), + ), 'Tool' + ) + ), + 'warnings' => new external_warnings(), + ) + ); + } + + /** + * Returns description of method parameters + * + * @return external_function_parameters + */ + public static function view_certificate_parameters() { + return new external_function_parameters( + array( + 'certificateid' => new external_value(PARAM_INT, 'certificate instance id') + ) + ); + } + + /** + * Trigger the course module viewed event and update the module completion status. + * + * @param int $certificateid the certificate instance id + * @return array of warnings and status result + * @throws moodle_exception + */ + public static function view_certificate($certificateid) { + global $DB; + + $params = self::validate_parameters(self::view_certificate_parameters(), + array( + 'certificateid' => $certificateid + ) + ); + $warnings = array(); + + // Request and permission validation. + $certificate = $DB->get_record('certificate', array('id' => $params['certificateid']), '*', MUST_EXIST); + list($course, $cm) = get_course_and_cm_from_instance($certificate, 'certificate'); + + $context = context_module::instance($cm->id); + self::validate_context($context); + require_capability('mod/certificate:view', $context); + + $event = \mod_certificate\event\course_module_viewed::create(array( + 'objectid' => $certificate->id, + 'context' => $context, + )); + $event->add_record_snapshot('course', $course); + $event->add_record_snapshot('certificate', $certificate); + $event->trigger(); + + $completion = new completion_info($course); + $completion->set_module_viewed($cm); + + $result = array(); + $result['status'] = true; + $result['warnings'] = $warnings; + return $result; + } + + /** + * Returns description of method result value + * + * @return external_description + */ + public static function view_certificate_returns() { + return new external_single_structure( + array( + 'status' => new external_value(PARAM_BOOL, 'status: true if success'), + 'warnings' => new external_warnings() + ) + ); + } + + /** + * Check if the user can issue certificates. + * + * @param int $certificateid certificate instance id + * @return array array containing context related data + */ + private static function check_can_issue($certificateid) { + global $DB; + + $certificate = $DB->get_record('certificate', array('id' => $certificateid), '*', MUST_EXIST); + list($course, $cm) = get_course_and_cm_from_instance($certificate, 'certificate'); + + $context = context_module::instance($cm->id); + self::validate_context($context); + require_capability('mod/certificate:view', $context); + + // Check if the user can view the certificate. + if ($certificate->requiredtime && !has_capability('mod/certificate:manage', $context)) { + if (certificate_get_course_time($course->id) < ($certificate->requiredtime * 60)) { + $a = new stdClass(); + $a->requiredtime = $certificate->requiredtime; + throw new moodle_exception('requiredtimenotmet', 'certificate', '', $a); + } + } + return array($certificate, $course, $cm, $context); + } + + /** + * Returns a issued certificated structure + * + * @return external_single_structure External single structure + */ + private static function issued_structure() { + return new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'Issue id'), + 'userid' => new external_value(PARAM_INT, 'User id'), + 'certificateid' => new external_value(PARAM_INT, 'Certificate id'), + 'code' => new external_value(PARAM_RAW, 'Certificate code'), + 'timecreated' => new external_value(PARAM_INT, 'Time created'), + 'filename' => new external_value(PARAM_FILE, 'Time created'), + 'fileurl' => new external_value(PARAM_URL, 'Time created'), + 'mimetype' => new external_value(PARAM_RAW, 'mime type'), + 'grade' => new external_value(PARAM_NOTAGS, 'Certificate grade', VALUE_OPTIONAL), + ) + ); + } + + /** + * Add extra required information to the issued certificate + * + * @param stdClass $issue issue object + * @param stdClass $certificate certificate object + * @param stdClass $course course object + * @param stdClass $cm course module object + * @param stdClass $context context object + */ + private static function add_extra_issue_data($issue, $certificate, $course, $cm, $context) { + global $CFG; + + // Grade data. + if ($certificate->printgrade) { + $issue->grade = certificate_get_grade($certificate, $course); + } + + // File data. + $issue->mimetype = 'application/pdf'; + $issue->filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.pdf'; + // We need to use a special file area to be able to download certificates (in most cases are not stored in the site). + $issue->fileurl = moodle_url::make_webservice_pluginfile_url( + $context->id, 'mod_certificate', 'onthefly', $issue->id, '/', $issue->filename)->out(false); + } + + /** + * Returns description of method parameters + * + * @return external_function_parameters + */ + public static function issue_certificate_parameters() { + return new external_function_parameters( + array( + 'certificateid' => new external_value(PARAM_INT, 'certificate instance id') + ) + ); + } + + /** + * Create new certificate record, or return existing record. + * + * @param int $certificateid the certificate instance id + * @return array of warnings and status result + * @throws moodle_exception + */ + public static function issue_certificate($certificateid) { + global $USER; + + $params = self::validate_parameters(self::issue_certificate_parameters(), + array( + 'certificateid' => $certificateid + ) + ); + $warnings = array(); + + // Request and permission validation. + list($certificate, $course, $cm, $context) = self::check_can_issue($params['certificateid']); + + $issue = certificate_get_issue($course, $USER, $certificate, $cm); + self::add_extra_issue_data($issue, $certificate, $course, $cm, $context); + + $result = array(); + $result['issue'] = $issue; + $result['warnings'] = $warnings; + return $result; + } + + /** + * Returns description of method result value + * + * @return external_description + */ + public static function issue_certificate_returns() { + return new external_single_structure( + array( + 'issue' => self::issued_structure(), + 'warnings' => new external_warnings() + ) + ); + } + + /** + * Returns description of method parameters + * + * @return external_function_parameters + */ + public static function get_issued_certificates_parameters() { + return new external_function_parameters( + array( + 'certificateid' => new external_value(PARAM_INT, 'certificate instance id') + ) + ); + } + + /** + * Get the list of issued certificates for the current user. + * + * @param int $certificateid the certificate instance id + * @return array of warnings and status result + * @throws moodle_exception + */ + public static function get_issued_certificates($certificateid) { + + $params = self::validate_parameters(self::get_issued_certificates_parameters(), + array( + 'certificateid' => $certificateid + ) + ); + $warnings = array(); + + // Request and permission validation. + list($certificate, $course, $cm, $context) = self::check_can_issue($params['certificateid']); + + $issues = certificate_get_attempts($certificate->id); + + if ($issues !== false ) { + foreach ($issues as $issue) { + self::add_extra_issue_data($issue, $certificate, $course, $cm, $context); + + } + } else { + $issues = array(); + } + + $result = array(); + $result['issues'] = $issues; + $result['warnings'] = $warnings; + return $result; + } + + /** + * Returns description of method result value + * + * @return external_description + */ + public static function get_issued_certificates_returns() { + return new external_single_structure( + array( + 'issues' => new external_multiple_structure(self::issued_structure()), + 'warnings' => new external_warnings() + ) + ); + } + +} diff --git a/classes/task/cron_task.php b/classes/task/cron_task.php new file mode 100644 index 0000000..865f20d --- /dev/null +++ b/classes/task/cron_task.php @@ -0,0 +1,16 @@ +dirroot . '/mod/certificate/lib.php'); + certificate_cron(); + } +} + +?> diff --git a/db/access.php b/db/access.php index bc7b822..b36b776 100644 --- a/db/access.php +++ b/db/access.php @@ -18,8 +18,7 @@ /** * Certificate module capability definition * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -66,9 +65,8 @@ $capabilities = array( 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW + 'editingteacher' => CAP_ALLOW ) ), -); \ No newline at end of file +); diff --git a/db/install.xml b/db/install.xml index 224ce0f..3121d7d 100644 --- a/db/install.xml +++ b/db/install.xml @@ -1,56 +1,56 @@ - - +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- +
- - - - - + + + + +
-
\ No newline at end of file + diff --git a/db/log.php b/db/log.php index c32db45..c545183 100644 --- a/db/log.php +++ b/db/log.php @@ -18,8 +18,7 @@ /** * Definition of log events * - * @package mod - * @subpackage lesson + * @package mod_certificate * @copyright 2010 Petr Skoda (http://skodak.org) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -31,4 +30,4 @@ $logs = array( array('module'=>'certificate', 'action'=>'add', 'mtable'=>'certificate', 'field'=>'name'), array('module'=>'certificate', 'action'=>'update', 'mtable'=>'certificate', 'field'=>'name'), array('module'=>'certificate', 'action'=>'received', 'mtable'=>'certificate', 'field'=>'name'), -); \ No newline at end of file +); diff --git a/db/mobile.php b/db/mobile.php new file mode 100644 index 0000000..f41916c --- /dev/null +++ b/db/mobile.php @@ -0,0 +1,27 @@ +. + +/** + * Certificate module capability definition + * + * @package mod_certificate + * @copyright 2016 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$addons = array( + "mod_certificate" => array() +); \ No newline at end of file diff --git a/db/services.php b/db/services.php new file mode 100644 index 0000000..e4f8335 --- /dev/null +++ b/db/services.php @@ -0,0 +1,64 @@ +. + +/** + * Certificate external functions and service definitions. + * + * @package mod_certificate + * @category external + * @copyright 2016 Juan Leyva + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$functions = array( + + 'mod_certificate_get_certificates_by_courses' => array( + 'classname' => 'mod_certificate_external', + 'methodname' => 'get_certificates_by_courses', + 'description' => 'Returns a list of certificate instances in a provided set of courses, if + no courses are provided then all the certificate instances the user has access to will be returned.', + 'type' => 'read', + 'capabilities' => 'mod/certificate:view', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE, 'local_mobile'), + ), + + 'mod_certificate_view_certificate' => array( + 'classname' => 'mod_certificate_external', + 'methodname' => 'view_certificate', + 'description' => 'Trigger the course module viewed event and update the module completion status.', + 'type' => 'write', + 'capabilities' => 'mod/certificate:view', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE, 'local_mobile'), + ), + + 'mod_certificate_issue_certificate' => array( + 'classname' => 'mod_certificate_external', + 'methodname' => 'issue_certificate', + 'description' => 'Create new certificate record, or return existing record for the current user.', + 'type' => 'write', + 'capabilities' => 'mod/certificate:view', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE, 'local_mobile'), + ), + + 'mod_certificate_get_issued_certificates' => array( + 'classname' => 'mod_certificate_external', + 'methodname' => 'get_issued_certificates', + 'description' => 'Get the list of issued certificates for the current user.', + 'type' => 'read', + 'capabilities' => 'mod/certificate:view', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE, 'local_mobile'), + ), +); diff --git a/db/tasks.php b/db/tasks.php new file mode 100644 index 0000000..c84c51b --- /dev/null +++ b/db/tasks.php @@ -0,0 +1,38 @@ +. + +/** + * Definition of Certificate scheduled tasks. + * + * @package mod_certificate + * @category task + * @copyright 2014 Dan Poltawski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$tasks = array( + array( + 'classname' => 'mod_certificate\task\cron_task', + 'blocking' => 0, + 'minute' => '*', + 'hour' => '*', + 'day' => '*', + 'month' => '*', + 'dayofweek' => '*' + ) +); diff --git a/db/upgrade.php b/db/upgrade.php index fb3e499..1311f47 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -18,8 +18,7 @@ /** * This file keeps track of upgrades to the certificate module * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -48,14 +47,14 @@ function xmldb_certificate_upgrade($oldversion=0) { $table = new xmldb_table('certificate'); $field = new xmldb_field('lockgrade'); - $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'printhours'); + $field->set_attributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'printhours'); if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } $table = new xmldb_table('certificate'); $field = new xmldb_field('requiredgrade'); - $field->set_attributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'lockgrade'); + $field->set_attributes(XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'lockgrade'); if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } @@ -63,12 +62,12 @@ function xmldb_certificate_upgrade($oldversion=0) { // Rename field save to savecert $field = new xmldb_field('save'); if ($dbman->field_exists($table, $field)) { - $field->set_attributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'emailothers'); + $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'emailothers'); // Launch rename field savecert $dbman->rename_field($table, $field, 'savecert'); } else { $field = new xmldb_field('savecert'); - $field->set_attributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'emailothers'); + $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'emailothers'); $dbman->add_field($table, $field); } @@ -79,11 +78,11 @@ function xmldb_certificate_upgrade($oldversion=0) { if ($oldversion < 2007061301) { $table = new xmldb_table('certificate_linked_modules'); - $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null); - $table->add_field('certificate_id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'id'); - $table->add_field('linkid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'certificate_id'); - $table->add_field('linkgrade', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'linkid'); - $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'linkgrade'); + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null); + $table->add_field('certificate_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id'); + $table->add_field('linkid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'certificate_id'); + $table->add_field('linkgrade', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'linkid'); + $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'linkgrade'); $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'), null, null); $table->add_index('certificate_id', XMLDB_INDEX_NOTUNIQUE, array('certificate_id')); $table->add_index('linkid', XMLDB_INDEX_NOTUNIQUE, array('linkid')); @@ -95,21 +94,11 @@ function xmldb_certificate_upgrade($oldversion=0) { upgrade_mod_savepoint(true, 2007061301, 'certificate'); } - if ($oldversion < 2007061302) { - $table = new xmldb_table('certificate_linked_modules'); - $field = new xmldb_field('linkid'); - $field->set_attributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'certificate_id'); - $dbman->change_field_unsigned($table, $field); - - // Certificate savepoint reached - upgrade_mod_savepoint(true, 2007061302, 'certificate'); - } - if ($oldversion < 2007102800) { // Add new fields to certificate table $table = new xmldb_table('certificate'); $field = new xmldb_field('reportcert'); - $field->set_attributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'savecert'); + $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'savecert'); if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } @@ -129,7 +118,7 @@ function xmldb_certificate_upgrade($oldversion=0) { // Add new fields to certificate table $table = new xmldb_table('certificate'); $field = new xmldb_field('printoutcome'); - $field->set_attributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'gradefmt'); + $field->set_attributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'gradefmt'); if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } @@ -157,7 +146,7 @@ function xmldb_certificate_upgrade($oldversion=0) { if ($oldversion < 2009062900) { // Add new field to certificate table $table = new xmldb_table('certificate'); - $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'intro'); + $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'intro'); if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } @@ -167,7 +156,7 @@ function xmldb_certificate_upgrade($oldversion=0) { $dbman->add_field($table, $field); } - $field = new xmldb_field('reissuecert', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'reportcert'); + $field = new xmldb_field('reissuecert', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'reportcert'); if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } @@ -196,7 +185,7 @@ function xmldb_certificate_upgrade($oldversion=0) { // Define field id to be added to certificate $table = new xmldb_table('certificate'); - $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'intro'); + $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, 0, 'intro'); // Conditionally launch add field id if (!$dbman->field_exists($table, $field)) { @@ -217,7 +206,7 @@ function xmldb_certificate_upgrade($oldversion=0) { // It is possible for these fields not to be added, ever, it is included in the upgrade // process but fresh certificate 1.9 install from CVS MOODLE_19_STABLE set the Moodle version // to 2009080900, which means it missed all the earlier code written for upgrading to 2.0. - $reissuefield = new xmldb_field('reissuecert', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'reportcert'); + $reissuefield = new xmldb_field('reissuecert', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'reportcert'); $orientationfield = new xmldb_field('orientation', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, ' ', 'certificatetype'); // Have to check, may be added during earlier upgrade, or may be missing due to not being included in install.xml @@ -399,7 +388,7 @@ function xmldb_certificate_upgrade($oldversion=0) { if ($oldversion < 2012072501) { // Add a column to store the required grade $table = new xmldb_table('certificate'); - $requiredtimefield = new xmldb_field('requiredtime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, + $requiredtimefield = new xmldb_field('requiredtime', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'delivery'); if (!$dbman->field_exists($table, $requiredtimefield)) { @@ -435,32 +424,32 @@ function xmldb_certificate_upgrade($oldversion=0) { $table = new xmldb_table('certificate'); // Change length of the fields that store images, so longer image names can be stored - $field = new xmldb_field('borderstyle', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, 0); + $field = new xmldb_field('borderstyle', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0); $dbman->change_field_precision($table, $field); - $field = new xmldb_field('printwmark', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, 0); + $field = new xmldb_field('printwmark', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0); $dbman->change_field_precision($table, $field); - $field = new xmldb_field('printsignature', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, 0); + $field = new xmldb_field('printsignature', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0); $dbman->change_field_precision($table, $field); - $field = new xmldb_field('printseal', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, 0); + $field = new xmldb_field('printseal', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0); $dbman->change_field_precision($table, $field); // Change length of fields that are unnecessarily large - $field = new xmldb_field('printnumber', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, 0, 0); + $field = new xmldb_field('printnumber', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0); $dbman->change_field_precision($table, $field); - $field = new xmldb_field('printhours', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, false, 0, 0); + $field = new xmldb_field('printhours', XMLDB_TYPE_CHAR, '255', null, false, 0, 0); $dbman->change_field_precision($table, $field); - $field = new xmldb_field('emailteachers', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, 0, 0); + $field = new xmldb_field('emailteachers', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0); $dbman->change_field_precision($table, $field); - $field = new xmldb_field('savecert', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, 0, 0); + $field = new xmldb_field('savecert', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0); $dbman->change_field_precision($table, $field); - $field = new xmldb_field('reportcert', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, 0, 0); + $field = new xmldb_field('reportcert', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, 0, 0); $dbman->change_field_precision($table, $field); // Certificate savepoint reached @@ -470,7 +459,7 @@ function xmldb_certificate_upgrade($oldversion=0) { if ($oldversion < 2012090901) { $table = new xmldb_table('certificate'); - $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, 0, 0, 'printseal'); + $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, 0, 0, 'printseal'); if (!$dbman->field_exists($table, $field)) { $dbman->add_field($table, $field); } @@ -484,5 +473,29 @@ function xmldb_certificate_upgrade($oldversion=0) { upgrade_mod_savepoint(true, 2012090901, 'certificate'); } + if ($oldversion < 2014081901) { + // Fix previous upgrades. + + $table = new xmldb_table('certificate'); + + $field = new xmldb_field('borderstyle', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0'); + $dbman->change_field_default($table, $field); + + $field = new xmldb_field('printwmark', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0'); + $dbman->change_field_default($table, $field); + + $field = new xmldb_field('printhours', XMLDB_TYPE_CHAR, '255', null, false, 0, null); + $dbman->change_field_default($table, $field); + + $field = new xmldb_field('printsignature', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0'); + $dbman->change_field_default($table, $field); + + $field = new xmldb_field('printseal', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, 0, '0'); + $dbman->change_field_default($table, $field); + + // Certificate savepoint reached. + upgrade_mod_savepoint(true, 2014081901, 'certificate'); + } + return true; } diff --git a/deprecatedlib.php b/deprecatedlib.php index 5f07fcd..cc89b98 100644 --- a/deprecatedlib.php +++ b/deprecatedlib.php @@ -18,8 +18,7 @@ /** * Deprecated certificate functions. * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/index.php b/index.php index 3581325..753b43d 100644 --- a/index.php +++ b/index.php @@ -18,14 +18,13 @@ /** * This page lists all the instances of certificate in a particular course * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once('../../config.php'); -require_once('lib.php'); +require_once('locallib.php'); $id = required_param('id', PARAM_INT); // Course Module ID @@ -35,7 +34,7 @@ if (!$course = $DB->get_record('course', array('id'=> $id))) { } // Requires a login -require_course_login($course); +require_login($course); // Declare variables $currentsection = ""; @@ -56,7 +55,11 @@ $PAGE->set_title($strcertificates); $PAGE->set_heading($course->fullname); // Add the page view to the Moodle log -add_to_log($course->id, 'certificate', 'view all', 'index.php?id='.$course->id, ''); +$event = \mod_certificate\event\course_module_instance_list_viewed::create(array( + 'context' => context_course::instance($course->id) +)); +$event->add_record_snapshot('course', $course); +$event->trigger(); // Get the certificates, if there are none display a notice if (!$certificates = get_all_instances_in_course('certificate', $course)) { @@ -115,4 +118,4 @@ foreach ($certificates as $certificate) { echo $OUTPUT->header(); echo '
'; echo html_writer::table($table); -echo $OUTPUT->footer(); \ No newline at end of file +echo $OUTPUT->footer(); diff --git a/lang/en/certificate.php b/lang/en/certificate.php index 2d79dc5..11fa8db 100644 --- a/lang/en/certificate.php +++ b/lang/en/certificate.php @@ -18,8 +18,7 @@ /** * Language strings for the certificate module * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -63,12 +62,14 @@ $string['certify'] = 'This is to certify that'; $string['certifyilb'] = 'This is to certify that'; $string['code'] = 'Code'; $string['completiondate'] = 'Course Completion'; +$string['completionrequired'] = '

You have not completed the course.


/n

While the criteria for course completion are not met, the certificate can not be issued.

'; $string['course'] = 'For'; $string['coursegrade'] = 'Course Grade'; $string['coursename'] = 'Course'; $string['coursetimereq'] = 'Required minutes in course'; $string['coursetimereq_help'] = 'Enter here the minimum amount of time, in minutes, that a student must be logged into the course before they will be able to receive the certificate.'; $string['credithours'] = 'Credit Hours'; +$string['crontask'] = 'Update users to generate certificates'; $string['customtext'] = 'Custom Text'; $string['customtext_help'] = 'If you want the certificate to print different names for the teacher than those who are assigned 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)).'; @@ -85,7 +86,7 @@ Email Certificate: Choosing this option sends the certificate to the student as 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.'; $string['designoptions'] = 'Design Options'; $string['download'] = 'Force download'; -$string['emailcertificate'] = 'Email (Must also choose save!)'; +$string['emailcertificate'] = 'Email'; $string['emailothers'] = 'Email Others'; $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.'; $string['emailstudenttext'] = 'Attached is your certificate for {$a->course}.'; @@ -106,6 +107,10 @@ You can review it here: Certificate Report.'; $string['entercode'] = 'Enter certificate code to verify:'; +$string['fontsans'] = 'Sans-serif font family'; +$string['fontsans_desc'] = 'Sans-serif font family for certificates with embedded fonts'; +$string['fontserif'] = 'Serif font family'; +$string['fontserif_desc'] = 'Serif font family for certificates with embedded fonts'; $string['getcertificate'] = 'Get your certificate'; $string['grade'] = 'Grade'; $string['gradedate'] = 'Grade Date'; @@ -119,7 +124,7 @@ $string['gradeletter'] = 'Letter Grade'; $string['gradepercent'] = 'Percentage Grade'; $string['gradepoints'] = 'Points Grade'; $string['imagetype'] = 'Image Type'; -$string['incompletemessage'] = 'In order to download your certificate, you must first complete all required '.'activities. Please return to the course to complete your coursework.'; +$string['incompletemessage'] = 'In order to download your certificate, you must first complete all required activities. Please return to the course to complete your coursework.'; $string['intro'] = 'Introduction'; $string['issueoptions'] = 'Issue Options'; $string['issued'] = 'Issued'; @@ -129,6 +134,8 @@ $string['lastviewed'] = 'You last received this certificate on:'; $string['letter'] = 'Letter'; $string['lockingoptions'] = 'Locking Options'; $string['modulename'] = 'Certificate'; +$string['modulename_help'] = 'This module allows for the dynamic generation of certificates based on predefined conditions set by the teacher.'; +$string['modulename_link'] = 'Certificate_module'; $string['modulenameplural'] = 'Certificates'; $string['mycertificates'] = 'My Certificates'; $string['nocertificates'] = 'There are no certificates'; @@ -185,7 +192,7 @@ $string['seal'] = 'Seal'; $string['sigline'] = 'line'; $string['signature'] = 'Signature'; $string['statement'] = 'has completed the course'; -$string['summaryofattempts'] = 'Summary of Previously Received Certificates'; +$string['summaryofattempts'] = 'Summary of previously received certificates'; $string['textoptions'] = 'Text Options'; $string['title'] = 'CERTIFICATE of ACHIEVEMENT'; $string['to'] = 'Awarded to'; @@ -203,5 +210,3 @@ $string['viewcertificateviews'] = 'View {$a} issued certificates'; $string['viewed'] = 'You received this certificate on:'; $string['viewtranscript'] = 'View Certificates'; $string['watermark'] = 'Watermark'; -$string['completionrequired'] = "

You have not completed the course.


-

While the criteria for course completion are not met, the certificate can not be issued.

"; diff --git a/lang/pt_br/certificate.php b/lang/pt_br/certificate.php index 6be6eab..f2721d9 100644 --- a/lang/pt_br/certificate.php +++ b/lang/pt_br/certificate.php @@ -69,6 +69,7 @@ $string['coursename'] = 'Course'; $string['coursetimereq'] = 'Required minutes in course'; $string['coursetimereq_help'] = 'Enter here the minimum amount of time, in minutes, that a student must be logged into the course before they will be able to receive the certificate.'; $string['credithours'] = 'Credit Hours'; +$string['crontask'] = 'Atualizar usuários para gerar certificados'; $string['customtext'] = 'Custom Text'; $string['customtext_help'] = 'If you want the certificate to print different names for the teacher than those who are assigned 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)).'; diff --git a/lib.php b/lib.php index 001b93f..2cab8fd 100644 --- a/lib.php +++ b/lib.php @@ -18,29 +18,14 @@ /** * Certificate module core interaction API * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -require_once($CFG->dirroot.'/course/lib.php'); -require_once($CFG->dirroot.'/grade/lib.php'); -require_once($CFG->dirroot.'/grade/querylib.php'); +defined('MOODLE_INTERNAL') || die(); -/** The border image folder */ -define('CERT_IMAGE_BORDER', 'borders'); -/** The watermark image folder */ -define('CERT_IMAGE_WATERMARK', 'watermarks'); -/** The signature image folder */ -define('CERT_IMAGE_SIGNATURE', 'signatures'); -/** The seal image folder */ -define('CERT_IMAGE_SEAL', 'seals'); - -/** Set CERT_PER_PAGE to 0 if you wish to display all certificates on the report page */ -define('CERT_PER_PAGE', 30); - -define('CERT_MAX_PER_PAGE', 200); +require_once($CFG->dirroot.'/mod/certificate/locallib.php'); /** * Add certificate instance. @@ -120,19 +105,31 @@ function certificate_delete_instance($id) { * @return array status array */ function certificate_reset_userdata($data) { - global $CFG, $DB; + global $DB; $componentstr = get_string('modulenameplural', 'certificate'); $status = array(); if (!empty($data->reset_certificate)) { $sql = "SELECT cert.id - FROM {certificate} cert - WHERE cert.course = :courseid"; - $DB->delete_records_select('certificate_issues', "certificateid IN ($sql)", array('courseid' => $data->courseid)); - $status[] = array('component' => $componentstr, 'item' => get_string('certificateremoved', 'certificate'), 'error' => false); - } + FROM {certificate} cert + WHERE cert.course = :courseid"; + $params = array('courseid' => $data->courseid); + $certificates = $DB->get_records_sql($sql, $params); + $fs = get_file_storage(); + if ($certificates) { + foreach ($certificates as $certid => $unused) { + if (!$cm = get_coursemodule_from_instance('certificate', $certid)) { + continue; + } + $context = context_module::instance($cm->id); + $fs->delete_area_files($context->id, 'mod_certificate', 'issue'); + } + } + $DB->delete_records_select('certificate_issues', "certificateid IN ($sql)", $params); + $status[] = array('component' => $componentstr, 'item' => get_string('removecert', 'certificate'), 'error' => false); + } // Updating dates - shift may be negative too if ($data->timeshift) { shift_course_mod_dates('certificate', array('timeopen', 'timeclose'), $data->timeshift, $data->courseid); @@ -198,17 +195,19 @@ function certificate_user_outline($course, $user, $mod, $certificate) { * @param stdClass $course * @param stdClass $user * @param stdClass $mod - * @param stdClass $page + * @param stdClass $certificate * @return string the user complete information */ function certificate_user_complete($course, $user, $mod, $certificate) { - global $DB, $OUTPUT; + global $DB, $OUTPUT, $CFG; + require_once($CFG->dirroot.'/mod/certificate/locallib.php'); - if ($issue = $DB->get_record('certificate_issues', array('certificateid' => $certificate->id, 'userid' => $user->id))) { + if ($issue = $DB->get_record('certificate_issues', array('certificateid' => $certificate->id, 'userid' => $user->id))) { echo $OUTPUT->box_start(); echo get_string('issued', 'certificate') . ": "; echo userdate($issue->timecreated); - certificate_print_user_files($certificate->id, $user->id); + $cm = get_coursemodule_from_instance('certificate', $certificate->id, $course->id); + certificate_print_user_files($certificate, $user->id, context_module::instance($cm->id)->id); echo '
'; echo $OUTPUT->box_end(); } else { @@ -227,9 +226,9 @@ function certificate_get_participants($certificateid) { global $DB; $sql = "SELECT DISTINCT u.id, u.id - FROM {user} u, {certificate_issues} a - WHERE a.certificateid = :certificateid - AND u.id = a.userid"; + FROM {user} u, {certificate_issues} a + WHERE a.certificateid = :certificateid + AND u.id = a.userid"; return $DB->get_records_sql($sql, array('certificateid' => $certificateid)); } @@ -257,293 +256,6 @@ function certificate_supports($feature) { } } -/** - * Function to be run periodically according to the moodle cron - * TODO:This needs to be done - */ -function certificate_cron () { - global $DB; - - $sql = "select distinct cm.id as cmid, c.*, ce.id as certificateid, ce.name as certificatename - from {certificate} ce - inner join {course} c on c.id = ce.course - inner join {course_modules} cm on cm.course = c.id and cm.instance = ce.id and cm.module = ? - where c.visible = 1 - order by c.id"; - - echo "\n\nGenerate certificates for user that has completed the course-------------------------\n"; - - $certmodule = $DB->get_record('modules', array('name' => 'certificate')); - $courses = $DB->get_records_sql($sql, array($certmodule->id)); - - $sql = "select u.* - from {course_completions} cc - inner join {user} u on u.id = cc.userid - where cc.course = ? - and cc.timecompleted is not null - and cc.userid not in (select ci.userid - from {certificate_issues} ci - where ci.certificateid = ?) - order by u.firstname"; - - foreach ($courses as $course) { - echo " Processing course {$course->fullname}, certificate: {$course->certificatename}...\n"; - $students = $DB->get_records_sql($sql, array($course->id, $course->certificateid)); - $total = count($students); - - if ($total > 0) { - echo " {$total} students without certificate found, generating certificates for them...\n"; - $certificate = $DB->get_record('certificate', array('id' => $course->certificateid)); - $cm = get_coursemodule_from_id('certificate', $course->cmid); - foreach ($students as $student) { - if (!$certificate->requiredtime or - (certificate_get_course_time($course->id) >= ($certificate->requiredtime * 60))) { - echo " generating issue certificate for {$student->firstname} {$student->lastname}..."; - $certrecord = certificate_get_issue($course, $student, $certificate, $cm); - echo " Done! Certificate {$certrecord->code} generated!\n"; - } else { - echo " {$student->firstname} {$student->lastname} has not required course time. Skiped!\n"; - } - } - } else { - echo " No students without certificate found! Course skipped.\n"; - } - } - - return true; -} - -/** - * Returns a list of teachers by group - * for sending email alerts to teachers - * - * @param stdClass $certificate - * @param stdClass $user - * @param stdClass $course - * @param stdClass $cm - * @return array the teacher array - */ -function certificate_get_teachers($certificate, $user, $course, $cm) { - global $USER, $DB; - - $context = context_module::instance($cm->id); - $potteachers = get_users_by_capability($context, 'mod/certificate:manage', - '', '', '', '', '', '', false, false); - if (empty($potteachers)) { - return array(); - } - $teachers = array(); - if (groups_get_activity_groupmode($cm, $course) == SEPARATEGROUPS) { // Separate groups are being used - if ($groups = groups_get_all_groups($course->id, $user->id)) { // Try to find all groups - foreach ($groups as $group) { - foreach ($potteachers as $t) { - if ($t->id == $user->id) { - continue; // do not send self - } - if (groups_is_member($group->id, $t->id)) { - $teachers[$t->id] = $t; - } - } - } - } else { - // user not in group, try to find teachers without group - foreach ($potteachers as $t) { - if ($t->id == $USER->id) { - continue; // do not send self - } - if (!groups_get_all_groups($course->id, $t->id)) { //ugly hack - $teachers[$t->id] = $t; - } - } - } - } else { - foreach ($potteachers as $t) { - if ($t->id == $USER->id) { - continue; // do not send self - } - $teachers[$t->id] = $t; - } - } - - return $teachers; -} - -/** - * Alerts teachers by email of received certificates. First checks - * whether the option to email teachers is set for this certificate. - * - * @param stdClass $course - * @param stdClass $certificate - * @param stdClass $certrecord - * @param stdClass $cm course module - */ -function certificate_email_teachers($course, $certificate, $certrecord, $cm) { - global $USER, $CFG, $DB; - - if ($certificate->emailteachers == 0) { // No need to do anything - return; - } - - $user = $DB->get_record('user', array('id' => $certrecord->userid)); - - if ($teachers = certificate_get_teachers($certificate, $user, $course, $cm)) { - $strawarded = get_string('awarded', 'certificate'); - foreach ($teachers as $teacher) { - $info = new stdClass; - $info->student = fullname($USER); - $info->course = format_string($course->fullname,true); - $info->certificate = format_string($certificate->name,true); - $info->url = $CFG->wwwroot.'/mod/certificate/report.php?id='.$cm->id; - $from = $USER; - $postsubject = $strawarded . ': ' . $info->student . ' -> ' . $certificate->name; - $posttext = certificate_email_teachers_text($info); - $posthtml = ($teacher->mailformat == 1) ? certificate_email_teachers_html($info) : ''; - - @email_to_user($teacher, $from, $postsubject, $posttext, $posthtml); // If it fails, oh well, too bad. - } - } -} - -/** - * Alerts others by email of received certificates. First checks - * whether the option to email others is set for this certificate. - * Uses the email_teachers info. - * Code suggested by Eloy Lafuente - * - * @param stdClass $course - * @param stdClass $certificate - * @param stdClass $certrecord - * @param stdClass $cm course module - */ -function certificate_email_others($course, $certificate, $certrecord, $cm) { - global $USER, $CFG, $DB; - - if ($certificate->emailothers) { - $others = explode(',', $certificate->emailothers); - if ($others) { - $strawarded = get_string('awarded', 'certificate'); - foreach ($others as $other) { - $other = trim($other); - if (validate_email($other)) { - $destination = new stdClass; - $destination->email = $other; - $info = new stdClass; - $info->student = fullname($USER); - $info->course = format_string($course->fullname, true); - $info->certificate = format_string($certificate->name, true); - $info->url = $CFG->wwwroot.'/mod/certificate/report.php?id='.$cm->id; - $from = $USER; - $postsubject = $strawarded . ': ' . $info->student . ' -> ' . $certificate->name; - $posttext = certificate_email_teachers_text($info); - $posthtml = certificate_email_teachers_html($info); - - @email_to_user($destination, $from, $postsubject, $posttext, $posthtml); // If it fails, oh well, too bad. - } - } - } - } -} - -/** - * Creates the text content for emails to teachers -- needs to be finished with cron - * - * @param $info object The info used by the 'emailteachermail' language string - * @return string - */ -function certificate_email_teachers_text($info) { - $posttext = get_string('emailteachermail', 'certificate', $info) . "\n"; - - return $posttext; -} - -/** - * Creates the html content for emails to teachers - * - * @param $info object The info used by the 'emailteachermailhtml' language string - * @return string - */ -function certificate_email_teachers_html($info) { - $posthtml = ''; - $posthtml .= '

' . get_string('emailteachermailhtml', 'certificate', $info) . '

'; - $posthtml .= '
'; - - return $posthtml; -} - -/** - * Sends the student their issued certificate from moddata as an email - * attachment. - * - * @param stdClass $course - * @param stdClass $certificate - * @param stdClass $certrecord - * @param stdClass $context - */ -function certificate_email_student($course, $certificate, $certrecord, $context) { - global $DB, $USER; - - // Get teachers - if ($users = get_users_by_capability($context, 'moodle/course:update', 'u.*', 'u.id ASC', - '', '', '', '', false, true)) { - $users = sort_by_roleassignment_authority($users, $context); - $teacher = array_shift($users); - } - - // If we haven't found a teacher yet, look for a non-editing teacher in this course. - if (empty($teacher) && $users = get_users_by_capability($context, 'moodle/course:update', 'u.*', 'u.id ASC', - '', '', '', '', false, true)) { - $users = sort_by_roleassignment_authority($users, $context); - $teacher = array_shift($users); - } - - // Ok, no teachers, use administrator name - if (empty($teacher)) { - $teacher = fullname(get_admin()); - } - - $info = new stdClass; - $info->username = fullname($USER); - $info->certificate = format_string($certificate->name, true); - $info->course = format_string($course->fullname, true); - $from = fullname($teacher); - $subject = $info->course . ': ' . $info->certificate; - $message = get_string('emailstudenttext', 'certificate', $info) . "\n"; - - // Make the HTML version more XHTML happy (&) - $messagehtml = text_to_html(get_string('emailstudenttext', 'certificate', $info)); - - // Remove full-stop at the end if it exists, to avoid "..pdf" being created and being filtered by clean_filename - $certname = rtrim($certificate->name, '.'); - $filename = clean_filename("$certname.pdf"); - - // Get hashed pathname - $fs = get_file_storage(); - - $component = 'mod_certificate'; - $filearea = 'issue'; - $filepath = '/'; - $files = $fs->get_area_files($context->id, $component, $filearea, $certrecord->id); - foreach ($files as $f) { - $filepathname = $f->get_contenthash(); - } - $attachment = 'filedir/'.certificate_path_from_hash($filepathname).'/'.$filepathname; - $attachname = $filename; - - return email_to_user($USER, $from, $subject, $message, $messagehtml, $attachment, $attachname); -} - -/** - * Retrieve certificate path from hash - * - * @param array $contenthash - * @return string the path - */ -function certificate_path_from_hash($contenthash) { - $l1 = $contenthash[0].$contenthash[1]; - $l2 = $contenthash[2].$contenthash[3]; - return "$l1/$l2"; -} - /** * Serves certificate issues and other files. * @@ -570,17 +282,18 @@ function certificate_pluginfile($course, $cm, $context, $filearea, $args, $force require_once($CFG->libdir.'/filelib.php'); - if ($filearea === 'issue') { - $certrecord = (int)array_shift($args); + $certrecord = (int)array_shift($args); - if (!$certrecord = $DB->get_record('certificate_issues', array('id' => $certrecord))) { - return false; - } + if (!$certrecord = $DB->get_record('certificate_issues', array('id' => $certrecord))) { + return false; + } - if ($USER->id != $certrecord->userid and !has_capability('mod/certificate:manage', $context)) { - return false; - } + $canmanagecertificate = has_capability('mod/certificate:manage', $context); + if ($USER->id != $certrecord->userid and !$canmanagecertificate) { + return false; + } + if ($filearea === 'issue') { $relativepath = implode('/', $args); $fullpath = "/{$context->id}/mod_certificate/issue/$certrecord->id/$relativepath"; @@ -589,988 +302,92 @@ function certificate_pluginfile($course, $cm, $context, $filearea, $args, $force return false; } send_stored_file($file, 0, 0, true); // download MUST be forced - security! - } -} - -/** - * This function returns success or failure of file save - * - * @param string $pdf is the string contents of the pdf - * @param int $certrecordid the certificate issue record id - * @param string $filename pdf filename - * @param int $contextid context id - * @return bool return true if successful, false otherwise - */ -function certificate_save_pdf($pdf, $certrecordid, $filename, $contextid) { - global $DB, $USER; - - if (empty($certrecordid)) { - return false; - } - - if (empty($pdf)) { - return false; - } - - $fs = get_file_storage(); - - // Prepare file record object - $component = 'mod_certificate'; - $filearea = 'issue'; - $filepath = '/'; - $fileinfo = array( - 'contextid' => $contextid, // ID of context - 'component' => $component, // usually = table name - 'filearea' => $filearea, // usually = table name - 'itemid' => $certrecordid, // usually = ID of row in table - 'filepath' => $filepath, // any path beginning and ending in / - 'filename' => $filename, // any filename - 'mimetype' => 'application/pdf', // any filename - 'userid' => $USER->id); - - // If the file exists, delete it and recreate it. This is to ensure that the - // latest certificate is saved on the server. For example, the student's grade - // may have been updated. This is a quick dirty hack. - if ($fs->file_exists($contextid, $component, $filearea, $certrecordid, $filepath, $filename)) { - $fs->delete_area_files($contextid, $component, $filearea, $certrecordid); - } - - $fs->create_file_from_string($fileinfo, $pdf); - - return true; -} - -/** - * Produces a list of links to the issued certificates. Used for report. - * - * @param stdClass $certificate - * @param int $userid - * @param stdClass $context - * @return string return the user files - */ -function certificate_print_user_files($certificate, $userid, $context) { - global $CFG, $DB, $OUTPUT; - - $output = ''; + } else if ($filearea === 'onthefly') { + require_once($CFG->dirroot.'/mod/certificate/locallib.php'); + require_once("$CFG->libdir/pdflib.php"); - $certrecord = $DB->get_record('certificate_issues', array('userid' => $userid, 'certificateid' => $certificate->id)); - $fs = get_file_storage(); - $browser = get_file_browser(); - - $component = 'mod_certificate'; - $filearea = 'issue'; - $files = $fs->get_area_files($context, $component, $filearea, $certrecord->id); - foreach ($files as $file) { - $filename = $file->get_filename(); - $mimetype = $file->get_mimetype(); - $link = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$context.'/mod_certificate/issue/'.$certrecord->id.'/'.$filename); + if (!$certificate = $DB->get_record('certificate', array('id' => $certrecord->certificateid))) { + return false; + } - $output = ''.$file->get_mimetype().' '. - ''.s($filename).''; + if ($certificate->requiredtime && !$canmanagecertificate) { + if (certificate_get_course_time($course->id) < ($certificate->requiredtime * 60)) { + return false; + } + } + // Load the specific certificate type. It will fill the $pdf var. + require("$CFG->dirroot/mod/certificate/type/$certificate->certificatetype/certificate.php"); + $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.pdf'; + $filecontents = $pdf->Output('', 'S'); + send_file($filecontents, $filename, 0, 0, true, true, 'application/pdf'); } - $output .= '
'; - $output = '
'.$output.'
'; - - return $output; } /** - * Inserts preliminary user data when a certificate is viewed. - * Prevents form from issuing a certificate upon browser refresh. + * Used for course participation report (in case certificate is added). * - * @param stdClass $course - * @param stdClass $user - * @param stdClass $certificate - * @param stdClass $cm - * @return stdClass the newly created certificate issue + * @return array */ -function certificate_get_issue($course, $user, $certificate, $cm) { - global $DB; - - // Check if there is an issue already, should only ever be one - if ($certissue = $DB->get_record('certificate_issues', array('userid' => $user->id, 'certificateid' => $certificate->id))) { - return $certissue; - } - - // Create new certificate issue record - $certissue = new stdClass(); - $certissue->certificateid = $certificate->id; - $certissue->userid = $user->id; - $certissue->code = certificate_generate_code(); - $certissue->timecreated = time(); - $certissue->id = $DB->insert_record('certificate_issues', $certissue); - - // Email to the teachers and anyone else - certificate_email_teachers($course, $certificate, $certissue, $cm); - certificate_email_others($course, $certificate, $certissue, $cm); - - return $certissue; +function certificate_get_view_actions() { + return array('view', 'view all', 'view report'); } /** - * Returns a list of issued certificates - sorted for report. + * Used for course participation report (in case certificate is added). * - * @param int $certificateid - * @param string $sort the sort order - * @param bool $groupmode are we in group mode ? - * @param stdClass $cm the course module - * @param int $page offset - * @param int $perpage total per page - * @return stdClass the users + * @return array */ -function certificate_get_issues($certificateid, $sort="ci.timecreated ASC", $groupmode, $cm, $page = 0, $perpage = 0) { - global $CFG, $DB; - - // get all users that can manage this certificate to exclude them from the report. - $context = context_module::instance($cm->id); - - $conditionssql = ''; - $conditionsparams = array(); - if ($certmanagers = array_keys(get_users_by_capability($context, 'mod/certificate:manage', 'u.id'))) { - list($sql, $params) = $DB->get_in_or_equal($certmanagers, SQL_PARAMS_NAMED, 'cert'); - $conditionssql .= "AND NOT u.id $sql \n"; - $conditionsparams += $params; - } - - - - $restricttogroup = false; - if ($groupmode) { - $currentgroup = groups_get_activity_group($cm); - if ($currentgroup) { - $restricttogroup = true; - $groupusers = array_keys(groups_get_members($currentgroup, 'u.*')); - if (empty($groupusers)) { - return array(); - } - } - } - - $restricttogrouping = false; - - // if groupmembersonly used, remove users who are not in any group - if (!empty($CFG->enablegroupings) and $cm->groupmembersonly) { - if ($groupingusers = groups_get_grouping_members($cm->groupingid, 'u.id', 'u.id')) { - $restricttogrouping = true; - } else { - return array(); - } - } - - if ($restricttogroup || $restricttogrouping) { - if ($restricttogroup) { - $allowedusers = $groupusers; - } else if ($restricttogroup && $restricttogrouping) { - $allowedusers = array_intersect($groupusers, $groupingusers); - } else { - $allowedusers = $groupingusers; - } - - list($sql, $params) = $DB->get_in_or_equal($allowedusers, SQL_PARAMS_NAMED, 'grp'); - $conditionssql .= "AND u.id $sql \n"; - $conditionsparams += $params; - } - - - $page = (int) $page; - $perpage = (int) $perpage; - - // Get all the users that have certificates issued, should only be one issue per user for a certificate - $allparams = $conditionsparams + array('certificateid' => $certificateid); - - $users = $DB->get_records_sql("SELECT u.*, ci.code, ci.timecreated - FROM {user} u - INNER JOIN {certificate_issues} ci - ON u.id = ci.userid - WHERE u.deleted = 0 - AND ci.certificateid = :certificateid - $conditionssql - ORDER BY {$sort}", - $allparams, - $page * $perpage, - $perpage); - - - return $users; +function certificate_get_post_actions() { + return array('received'); } /** - * Returns a list of previously issued certificates--used for reissue. - * - * @param int $certificateid - * @return stdClass the attempts else false if none found + * Function to be run periodically according to the moodle cron + * TODO:This needs to be done */ -function certificate_get_attempts($certificateid) { - global $DB, $USER; - - $sql = "SELECT * - FROM {certificate_issues} i - WHERE certificateid = :certificateid - AND userid = :userid"; - if ($issues = $DB->get_records_sql($sql, array('certificateid' => $certificateid, 'userid' => $USER->id))) { - return $issues; - } - - return false; -} - -/** - * Prints a table of previously issued certificates--used for reissue. - * - * @param stdClass $course - * @param stdClass $certificate - * @param stdClass $attempts - * @return string the attempt table - */ -function certificate_print_attempts($course, $certificate, $attempts) { - global $OUTPUT, $DB; - - echo $OUTPUT->heading(get_string('summaryofattempts', 'certificate')); - - // Prepare table header - $table = new html_table(); - $table->class = 'generaltable'; - $table->head = array(get_string('issued', 'certificate')); - $table->align = array('left'); - $table->attributes = array("style" => "width:20%; margin:auto"); - $gradecolumn = $certificate->printgrade; - if ($gradecolumn) { - $table->head[] = get_string('grade'); - $table->align[] = 'center'; - $table->size[] = ''; - } - // One row for each attempt - foreach ($attempts as $attempt) { - $row = array(); - - // prepare strings for time taken and date completed - $datecompleted = userdate($attempt->timecreated); - $row[] = $datecompleted; - - if ($gradecolumn) { - $attemptgrade = certificate_get_grade($certificate, $course); - $row[] = $attemptgrade; - } - - $table->data[$attempt->id] = $row; - } - - echo html_writer::table($table); -} - -/** - * Get the time the user has spent in the course - * - * @param int $courseid - * @return int the total time spent in seconds - */ -function certificate_get_course_time($courseid) { - global $CFG, $USER; - - set_time_limit(0); - - $totaltime = 0; - $sql = "l.course = :courseid AND l.userid = :userid"; - if ($logs = get_logs($sql, array('courseid' => $courseid, 'userid' => $USER->id), 'l.time ASC', '', '', $totalcount)) { - foreach ($logs as $log) { - if (!isset($login)) { - // For the first time $login is not set so the first log is also the first login - $login = $log->time; - $lasthit = $log->time; - $totaltime = 0; - } - $delay = $log->time - $lasthit; - if ($delay > ($CFG->sessiontimeout * 60)) { - // The difference between the last log and the current log is more than - // the timeout Register session value so that we have found a session! - $login = $log->time; - } else { - $totaltime += $delay; - } - // Now the actual log became the previous log for the next cycle - $lasthit = $log->time; - } - - return $totaltime; - } - - return 0; -} - -/** - * Get all the modules - * - * @return array - */ -function certificate_get_mods() { - global $COURSE, $DB; - - $strtopic = get_string("topic"); - $strweek = get_string("week"); - $strsection = get_string("section"); - - // Collect modules data - $modinfo = get_fast_modinfo($COURSE); - $mods = $modinfo->get_cms(); - - $modules = array(); - $sections = $modinfo->get_section_info_all(); - for ($i = 0; $i <= count($sections) - 1; $i++) { - // should always be true - if (isset($sections[$i])) { - $section = $sections[$i]; - if ($section->sequence) { - switch ($COURSE->format) { - case "topics": - $sectionlabel = $strtopic; - break; - case "weeks": - $sectionlabel = $strweek; - break; - default: - $sectionlabel = $strsection; - } - - $sectionmods = explode(",", $section->sequence); - foreach ($sectionmods as $sectionmod) { - if (empty($mods[$sectionmod])) { - continue; - } - $mod = $mods[$sectionmod]; - $instance = $DB->get_record($mod->modname, array('id' => $mod->instance)); - if ($grade_items = grade_get_grade_items_for_activity($mod)) { - $mod_item = grade_get_grades($COURSE->id, 'mod', $mod->modname, $mod->instance); - $item = reset($mod_item->items); - if (isset($item->grademax)){ - $modules[$mod->id] = $sectionlabel . ' ' . $section->section . ' : ' . $instance->name; - } - } - } - } - } - } - - return $modules; -} - -/** - * Search through all the modules for grade data for mod_form. - * - * @return array - */ -function certificate_get_grade_options() { - $gradeoptions['0'] = get_string('no'); - $gradeoptions['1'] = get_string('coursegrade', 'certificate'); - - return $gradeoptions; -} - -/** - * Search through all the modules for grade dates for mod_form. - * - * @return array - */ -function certificate_get_date_options() { - $dateoptions['0'] = get_string('no'); - $dateoptions['1'] = get_string('issueddate', 'certificate'); - $dateoptions['2'] = get_string('completiondate', 'certificate'); - - return $dateoptions; -} - -/** - * Fetch all grade categories from the specified course. - * - * @param int $courseid the course id - * @return array - */ -function certificate_get_grade_categories($courseid) { - $grade_category_options = array(); - - if ($grade_categories = grade_category::fetch_all(array('courseid' => $courseid))) { - foreach ($grade_categories as $grade_category) { - if (!$grade_category->is_course_category()) { - $grade_category_options[-$grade_category->id] = get_string('category') . ' : ' . $grade_category->get_name(); - } - } - } - - return $grade_category_options; -} - -/** - * Get the course outcomes for for mod_form print outcome. - * - * @return array - */ -function certificate_get_outcomes() { - global $COURSE, $DB; - - // get all outcomes in course - $grade_seq = new grade_tree($COURSE->id, false, true, '', false); - if ($grade_items = $grade_seq->items) { - // list of item for menu - $printoutcome = array(); - foreach ($grade_items as $grade_item) { - if (isset($grade_item->outcomeid)){ - $itemmodule = $grade_item->itemmodule; - $printoutcome[$grade_item->id] = $itemmodule . ': ' . $grade_item->get_name(); - } - } - } - if (isset($printoutcome)) { - $outcomeoptions['0'] = get_string('no'); - foreach ($printoutcome as $key => $value) { - $outcomeoptions[$key] = $value; - } - } else { - $outcomeoptions['0'] = get_string('nooutcomes', 'certificate'); - } - - return $outcomeoptions; -} - -/** - * Used for course participation report (in case certificate is added). - * - * @return array - */ -function certificate_get_view_actions() { - return array('view', 'view all', 'view report'); -} - -/** - * Used for course participation report (in case certificate is added). - * - * @return array - */ -function certificate_get_post_actions() { - return array('received'); -} - -/** - * Get certificate types indexed and sorted by name for mod_form. - * - * @return array containing the certificate type - */ -function certificate_types() { - $types = array(); - $names = get_list_of_plugins('mod/certificate/type'); - $sm = get_string_manager(); - foreach ($names as $name) { - if ($sm->string_exists('type'.$name, 'certificate')) { - $types[$name] = get_string('type'.$name, 'certificate'); - } else { - $types[$name] = ucfirst($name); - } - } - asort($types); - return $types; -} - -/** - * Get images for mod_form. - * - * @param string $type the image type - * @return array - */ -function certificate_get_images($type) { - global $CFG, $DB; - - switch($type) { - case CERT_IMAGE_BORDER : - $path = "$CFG->dirroot/mod/certificate/pix/borders"; - $uploadpath = "$CFG->dataroot/mod/certificate/pix/borders"; - break; - case CERT_IMAGE_SEAL : - $path = "$CFG->dirroot/mod/certificate/pix/seals"; - $uploadpath = "$CFG->dataroot/mod/certificate/pix/seals"; - break; - case CERT_IMAGE_SIGNATURE : - $path = "$CFG->dirroot/mod/certificate/pix/signatures"; - $uploadpath = "$CFG->dataroot/mod/certificate/pix/signatures"; - break; - case CERT_IMAGE_WATERMARK : - $path = "$CFG->dirroot/mod/certificate/pix/watermarks"; - $uploadpath = "$CFG->dataroot/mod/certificate/pix/watermarks"; - break; - } - // If valid path - if (!empty($path)) { - $options = array(); - $options += certificate_scan_image_dir($path); - $options += certificate_scan_image_dir($uploadpath); - - // Sort images - ksort($options); - - // Add the 'no' option to the top of the array - $options = array_merge(array('0' => get_string('no')), $options); - - return $options; - } else { - return array(); - } -} - -/** - * Prepare to print an activity grade. - * - * @param stdClass $course - * @param int $moduleid - * @param int $userid - * @return stdClass|bool return the mod object if it exists, false otherwise - */ -function certificate_get_mod_grade($course, $moduleid, $userid) { +function certificate_cron () { global $DB; - - $cm = $DB->get_record('course_modules', array('id' => $moduleid)); - $module = $DB->get_record('modules', array('id' => $cm->module)); - - if ($grade_item = grade_get_grades($course->id, 'mod', $module->name, $cm->instance, $userid)) { - $item = new grade_item(); - $itemproperties = reset($grade_item->items); - foreach ($itemproperties as $key => $value) { - $item->$key = $value; - } - $modinfo = new stdClass; - $modinfo->name = utf8_decode($DB->get_field($module->name, 'name', array('id' => $cm->instance))); - $grade = $item->grades[$userid]->grade; - $item->gradetype = GRADE_TYPE_VALUE; - $item->courseid = $course->id; - - $modinfo->points = grade_format_gradevalue($grade, $item, true, GRADE_DISPLAY_TYPE_REAL, $decimals = 2); - $modinfo->percentage = grade_format_gradevalue($grade, $item, true, GRADE_DISPLAY_TYPE_PERCENTAGE, $decimals = 2); - $modinfo->letter = grade_format_gradevalue($grade, $item, true, GRADE_DISPLAY_TYPE_LETTER, $decimals = 0); - - if ($grade) { - $modinfo->dategraded = $item->grades[$userid]->dategraded; - } else { - $modinfo->dategraded = time(); - } - return $modinfo; - } - - return false; -} - -/** - * Returns the date to display for the certificate. - * - * @param stdClass $certificate - * @param stdClass $certrecord - * @param stdClass $course - * @param int $userid - * @return string the date - */ -function certificate_get_date($certificate, $certrecord, $course, $userid = null) { - global $DB, $USER; - - if (empty($userid)) { - $userid = $USER->id; - } - - // Set certificate date to current time, can be overwritten later - $date = $certrecord->timecreated; - - if ($certificate->printdate == '2') { - // Get the enrolment end date - $sql = "SELECT MAX(c.timecompleted) as timecompleted - FROM {course_completions} c - WHERE c.userid = :userid - AND c.course = :courseid"; - if ($timecompleted = $DB->get_record_sql($sql, array('userid' => $userid, 'courseid' => $course->id))) { - if (!empty($timecompleted->timecompleted)) { - $date = $timecompleted->timecompleted; - } - } - } else if ($certificate->printdate > 2) { - if ($modinfo = certificate_get_mod_grade($course, $certificate->printdate, $userid)) { - $date = $modinfo->dategraded; - } - } - if ($certificate->printdate > 0) { - if ($certificate->datefmt == 1) { - $certificatedate = userdate($date, '%B %d, %Y'); - } else if ($certificate->datefmt == 2) { - $suffix = certificate_get_ordinal_number_suffix(userdate($date, '%d')); - $certificatedate = userdate($date, '%B %d' . $suffix . ', %Y'); - } else if ($certificate->datefmt == 3) { - $certificatedate = userdate($date, '%d de %B de %Y'); - } else if ($certificate->datefmt == 4) { - $certificatedate = userdate($date, '%B %Y'); - } else if ($certificate->datefmt == 5) { - $certificatedate = userdate($date, get_string('strftimedate', 'langconfig')); - } - - return $certificatedate; - } - - return ''; -} - -/** - * Helper function to return the suffix of the day of - * the month, eg 'st' if it is the 1st of the month. - * - * @param int the day of the month - * @return string the suffix. - */ -function certificate_get_ordinal_number_suffix($day) { - if (!in_array(($day % 100), array(11, 12, 13))) { - switch ($day % 10) { - // Handle 1st, 2nd, 3rd - case 1: return 'st'; - case 2: return 'nd'; - case 3: return 'rd'; - } - } - return 'th'; -} - -/** - * Returns the grade to display for the certificate. - * - * @param stdClass $certificate - * @param stdClass $course - * @param int $userid - * @return string the grade result - */ -function certificate_get_grade($certificate, $course, $userid = null) { - global $USER, $DB; - - if (empty($userid)) { - $userid = $USER->id; - } - - if ($certificate->printgrade > 0) { - if ($certificate->printgrade == 1) { - if ($course_item = grade_item::fetch_course_item($course->id)) { - // String used - $strcoursegrade = get_string('coursegrade', 'certificate'); - - $grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $userid)); - $course_item->gradetype = GRADE_TYPE_VALUE; - $coursegrade = new stdClass; - $coursegrade->points = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_REAL, $decimals = 2); - $coursegrade->percentage = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE, $decimals = 2); - $coursegrade->letter = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_LETTER, $decimals = 0); - - if ($certificate->gradefmt == 1) { - $grade = $strcoursegrade . ': ' . $coursegrade->percentage; - } else if ($certificate->gradefmt == 2) { - $grade = $strcoursegrade . ': ' . $coursegrade->points; - } else if ($certificate->gradefmt == 3) { - $grade = $strcoursegrade . ': ' . $coursegrade->letter; - } - - return $grade; - } - } else { // Print the mod grade - if ($modinfo = certificate_get_mod_grade($course, $certificate->printgrade, $userid)) { - // String used - $strgrade = get_string('grade', 'certificate'); - if ($certificate->gradefmt == 1) { - $grade = $modinfo->name . ' ' . $strgrade . ': ' . $modinfo->percentage; - } else if ($certificate->gradefmt == 2) { - $grade = $modinfo->name . ' ' . $strgrade . ': ' . $modinfo->points; - } else if ($certificate->gradefmt == 3) { - $grade = $modinfo->name . ' ' . $strgrade . ': ' . $modinfo->letter; - } - - return $grade; - } - } - } else if ($certificate->printgrade < 0) { // Must be a category id. - if ($category_item = grade_item::fetch(array('itemtype' => 'category', 'iteminstance' => -$certificate->printgrade))) { - $category_item->gradetype = GRADE_TYPE_VALUE; - - $grade = new grade_grade(array('itemid' => $category_item->id, 'userid' => $userid)); - - $category_grade = new stdClass; - $category_grade->points = grade_format_gradevalue($grade->finalgrade, $category_item, true, GRADE_DISPLAY_TYPE_REAL, $decimals = 2); - $category_grade->percentage = grade_format_gradevalue($grade->finalgrade, $category_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE, $decimals = 2); - $category_grade->letter = grade_format_gradevalue($grade->finalgrade, $category_item, true, GRADE_DISPLAY_TYPE_LETTER, $decimals = 0); - - if ($certificate->gradefmt == 1) { - $formattedgrade = $category_grade->percentage; - } else if ($certificate->gradefmt == 2) { - $formattedgrade = $category_grade->points; - } else if ($certificate->gradefmt == 3) { - $formattedgrade = $category_grade->letter; + $sql = "select distinct cm.id as cmid, c.*, ce.id as certificateid, ce.name as certificatename + from {certificate} ce + inner join {course} c on c.id = ce.course + inner join {course_modules} cm on cm.course = c.id and cm.instance = ce.id and cm.module = ? + where c.visible = 1 + order by c.id"; + echo "\n\nGenerate certificates for user that has completed the course-------------------------\n"; + $certmodule = $DB->get_record('modules', array('name' => 'certificate')); + $courses = $DB->get_records_sql($sql, array($certmodule->id)); + $sql = "select u.* + from {course_completions} cc + inner join {user} u on u.id = cc.userid + where cc.course = ? + and cc.timecompleted is not null + and cc.userid not in (select ci.userid + from {certificate_issues} ci + where ci.certificateid = ?) + order by u.firstname"; + foreach ($courses as $course) { + echo " Processing course {$course->fullname}, certificate: {$course->certificatename}...\n"; + $students = $DB->get_records_sql($sql, array($course->id, $course->certificateid)); + $total = count($students); + if ($total > 0) { + echo " {$total} students without certificate found, generating certificates for them...\n"; + $certificate = $DB->get_record('certificate', array('id' => $course->certificateid)); + $cm = get_coursemodule_from_id('certificate', $course->cmid); + foreach ($students as $student) { + if (!$certificate->requiredtime or + (certificate_get_course_time($course->id) >= ($certificate->requiredtime * 60))) { + echo " generating issue certificate for {$student->firstname} {$student->lastname}..."; + $certrecord = certificate_get_issue($course, $student, $certificate, $cm); + echo " Done! Certificate {$certrecord->code} generated!\n"; + } else { + echo " {$student->firstname} {$student->lastname} has not required course time. Skiped!\n"; + } } - - return $formattedgrade; - } - } - - return ''; -} - -/** - * Returns the outcome to display on the certificate - * - * @param stdClass $certificate - * @param stdClass $course - * @return string the outcome - */ -function certificate_get_outcome($certificate, $course) { - global $USER, $DB; - - if ($certificate->printoutcome > 0) { - if ($grade_item = new grade_item(array('id' => $certificate->printoutcome))) { - $outcomeinfo = new stdClass; - $outcomeinfo->name = $grade_item->get_name(); - $outcome = new grade_grade(array('itemid' => $grade_item->id, 'userid' => $USER->id)); - $outcomeinfo->grade = grade_format_gradevalue($outcome->finalgrade, $grade_item, true, GRADE_DISPLAY_TYPE_REAL); - - return $outcomeinfo->name . ': ' . $outcomeinfo->grade; - } - } - - return ''; -} - -/** - * Returns the code to display on the certificate. - * - * @param stdClass $course - * @param stdClass $certrecord - * @return string the code - */ -function certificate_get_code($certificate, $certrecord) { - if ($certificate->printnumber) { - return $certrecord->code; - } - - return ''; -} - -/** - * Sends text to output given the following params. - * - * @param stdClass $pdf - * @param int $x horizontal position - * @param int $y vertical position - * @param char $align L=left, C=center, R=right - * @param string $font any available font in font directory - * @param char $style ''=normal, B=bold, I=italic, U=underline - * @param int $size font size in points - * @param string $text the text to print - * @param int $width horizontal dimension of text block - */ -function certificate_print_text($pdf, $x, $y, $align, $font='freeserif', $style, $size = 10, $text, $width = 0) { - $pdf->setFont($font, $style, $size); - $pdf->SetXY($x, $y); - $pdf->writeHTMLCell($width, 0, '', '', $text, 0, 0, 0, true, $align); -} - -/** - * Creates rectangles for line border for A4 size paper. - * - * @param stdClass $pdf - * @param stdClass $certificate - */ -function certificate_draw_frame($pdf, $certificate) { - if ($certificate->bordercolor > 0) { - if ($certificate->bordercolor == 1) { - $color = array(0, 0, 0); // black - } - if ($certificate->bordercolor == 2) { - $color = array(153, 102, 51); // brown - } - if ($certificate->bordercolor == 3) { - $color = array(0, 51, 204); // blue - } - if ($certificate->bordercolor == 4) { - $color = array(0, 180, 0); // green - } - switch ($certificate->orientation) { - case 'L': - // create outer line border in selected color - $pdf->SetLineStyle(array('width' => 1.5, 'color' => $color)); - $pdf->Rect(10, 10, 277, 190); - // create middle line border in selected color - $pdf->SetLineStyle(array('width' => 0.2, 'color' => $color)); - $pdf->Rect(13, 13, 271, 184); - // create inner line border in selected color - $pdf->SetLineStyle(array('width' => 1.0, 'color' => $color)); - $pdf->Rect(16, 16, 265, 178); - break; - case 'P': - // create outer line border in selected color - $pdf->SetLineStyle(array('width' => 1.5, 'color' => $color)); - $pdf->Rect(10, 10, 190, 277); - // create middle line border in selected color - $pdf->SetLineStyle(array('width' => 0.2, 'color' => $color)); - $pdf->Rect(13, 13, 184, 271); - // create inner line border in selected color - $pdf->SetLineStyle(array('width' => 1.0, 'color' => $color)); - $pdf->Rect(16, 16, 178, 265); - break; - } - } -} - -/** - * Creates rectangles for line border for letter size paper. - * - * @param stdClass $pdf - * @param stdClass $certificate - */ -function certificate_draw_frame_letter($pdf, $certificate) { - if ($certificate->bordercolor > 0) { - if ($certificate->bordercolor == 1) { - $color = array(0, 0, 0); //black - } - if ($certificate->bordercolor == 2) { - $color = array(153, 102, 51); //brown - } - if ($certificate->bordercolor == 3) { - $color = array(0, 51, 204); //blue - } - if ($certificate->bordercolor == 4) { - $color = array(0, 180, 0); //green - } - switch ($certificate->orientation) { - case 'L': - // create outer line border in selected color - $pdf->SetLineStyle(array('width' => 4.25, 'color' => $color)); - $pdf->Rect(28, 28, 736, 556); - // create middle line border in selected color - $pdf->SetLineStyle(array('width' => 0.2, 'color' => $color)); - $pdf->Rect(37, 37, 718, 538); - // create inner line border in selected color - $pdf->SetLineStyle(array('width' => 2.8, 'color' => $color)); - $pdf->Rect(46, 46, 700, 520); - break; - case 'P': - // create outer line border in selected color - $pdf->SetLineStyle(array('width' => 1.5, 'color' => $color)); - $pdf->Rect(25, 20, 561, 751); - // create middle line border in selected color - $pdf->SetLineStyle(array('width' => 0.2, 'color' => $color)); - $pdf->Rect(40, 35, 531, 721); - // create inner line border in selected color - $pdf->SetLineStyle(array('width' => 1.0, 'color' => $color)); - $pdf->Rect(51, 46, 509, 699); - break; - } - } -} - -/** - * Prints border images from the borders folder in PNG or JPG formats. - * - * @param stdClass $pdf; - * @param stdClass $certificate - * @param int $x x position - * @param int $y y position - * @param int $w the width - * @param int $h the height - */ -function certificate_print_image($pdf, $certificate, $type, $x, $y, $w, $h) { - global $CFG; - - switch($type) { - case CERT_IMAGE_BORDER : - $attr = 'borderstyle'; - $path = "$CFG->dirroot/mod/certificate/pix/$type/$certificate->borderstyle"; - $uploadpath = "$CFG->dataroot/mod/certificate/pix/$type/$certificate->borderstyle"; - break; - case CERT_IMAGE_SEAL : - $attr = 'printseal'; - $path = "$CFG->dirroot/mod/certificate/pix/$type/$certificate->printseal"; - $uploadpath = "$CFG->dataroot/mod/certificate/pix/$type/$certificate->printseal"; - break; - case CERT_IMAGE_SIGNATURE : - $attr = 'printsignature'; - $path = "$CFG->dirroot/mod/certificate/pix/$type/$certificate->printsignature"; - $uploadpath = "$CFG->dataroot/mod/certificate/pix/$type/$certificate->printsignature"; - break; - case CERT_IMAGE_WATERMARK : - $attr = 'printwmark'; - $path = "$CFG->dirroot/mod/certificate/pix/$type/$certificate->printwmark"; - $uploadpath = "$CFG->dataroot/mod/certificate/pix/$type/$certificate->printwmark"; - break; - } - // Has to be valid - if (!empty($path)) { - switch ($certificate->$attr) { - case '0' : - case '' : - break; - default : - if (file_exists($path)) { - $pdf->Image($path, $x, $y, $w, $h); - } - if (file_exists($uploadpath)) { - $pdf->Image($uploadpath, $x, $y, $w, $h); - } - break; - } - } -} - -function custom_random_string($length=15) { - $pool = 'ABCDEFGHJKMNOPQRSTUVWXYZ'; - $pool .= 'abcdefghjkmnopqrstuvwxyz'; - $pool .= '0123456789'; - $poollen = strlen($pool); - $string = ''; - for($i=0; $i < $length; $i++) { - $string .= substr($pool, (mt_rand()%($poollen)), 1); - } - return $string; -} - -/** - * Generates a 10-digit code of random letters and numbers. - * - * @return string - */ -function certificate_generate_code() { - global $DB; - - $uniquecodefound = false; - $code = custom_random_string(10); - while (!$uniquecodefound) { - if (!$DB->record_exists('certificate_issues', array('code' => $code))) { - $uniquecodefound = true; } else { - $code = custom_random_string(10); - } - } - - return $code; -} - -/** - * Scans directory for valid images - * - * @param string the path - * @return array - */ -function certificate_scan_image_dir($path) { - // Array to store the images - $options = array(); - - // Start to scan directory - if (is_dir($path)) { - if ($handle = opendir($path)) { - while (false !== ($file = readdir($handle))) { - if (strpos($file, '.png', 1) || strpos($file, '.jpg', 1) ) { - $i = strpos($file, '.'); - if ($i > 1) { - // Set the name - $options[$file] = substr($file, 0, $i); - } - } - } - closedir($handle); + echo " No students without certificate found! Course skipped.\n"; } } - - return $options; + + return true; } diff --git a/locallib.php b/locallib.php new file mode 100644 index 0000000..97e0f1b --- /dev/null +++ b/locallib.php @@ -0,0 +1,1293 @@ +. + +/** + * Certificate module internal API, + * this is in separate file to reduce memory use on non-certificate pages. + * + * @package mod_certificate + * @copyright Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->dirroot.'/mod/certificate/lib.php'); +require_once($CFG->dirroot.'/course/lib.php'); +require_once($CFG->dirroot.'/grade/lib.php'); +require_once($CFG->dirroot.'/grade/querylib.php'); + +/** The border image folder */ +define('CERT_IMAGE_BORDER', 'borders'); +/** The watermark image folder */ +define('CERT_IMAGE_WATERMARK', 'watermarks'); +/** The signature image folder */ +define('CERT_IMAGE_SIGNATURE', 'signatures'); +/** The seal image folder */ +define('CERT_IMAGE_SEAL', 'seals'); + +/** Set CERT_PER_PAGE to 0 if you wish to display all certificates on the report page */ +define('CERT_PER_PAGE', 30); + +define('CERT_MAX_PER_PAGE', 200); + + +/** + * Returns a list of teachers by group + * for sending email alerts to teachers + * + * @param stdClass $certificate + * @param stdClass $user + * @param stdClass $course + * @param stdClass $cm + * @return array the teacher array + */ +function certificate_get_teachers($certificate, $user, $course, $cm) { + global $USER; + + $context = context_module::instance($cm->id); + $potteachers = get_users_by_capability($context, 'mod/certificate:manage', + '', '', '', '', '', '', false, false); + if (empty($potteachers)) { + return array(); + } + $teachers = array(); + if (groups_get_activity_groupmode($cm, $course) == SEPARATEGROUPS) { // Separate groups are being used + if ($groups = groups_get_all_groups($course->id, $user->id)) { // Try to find all groups + foreach ($groups as $group) { + foreach ($potteachers as $t) { + if ($t->id == $user->id) { + continue; // do not send self + } + if (groups_is_member($group->id, $t->id)) { + $teachers[$t->id] = $t; + } + } + } + } else { + // user not in group, try to find teachers without group + foreach ($potteachers as $t) { + if ($t->id == $USER->id) { + continue; // do not send self + } + if (!groups_get_all_groups($course->id, $t->id)) { //ugly hack + $teachers[$t->id] = $t; + } + } + } + } else { + foreach ($potteachers as $t) { + if ($t->id == $USER->id) { + continue; // do not send self + } + $teachers[$t->id] = $t; + } + } + + return $teachers; +} + +/** + * Alerts teachers by email of received certificates. First checks + * whether the option to email teachers is set for this certificate. + * + * @param stdClass $course + * @param stdClass $certificate + * @param stdClass $certrecord + * @param stdClass $cm course module + */ +function certificate_email_teachers($course, $certificate, $certrecord, $cm) { + global $USER, $CFG, $DB; + + if ($certificate->emailteachers == 0) { // No need to do anything + return; + } + + $user = $DB->get_record('user', array('id' => $certrecord->userid)); + + if ($teachers = certificate_get_teachers($certificate, $user, $course, $cm)) { + $strawarded = get_string('awarded', 'certificate'); + foreach ($teachers as $teacher) { + $info = new stdClass; + $info->student = fullname($USER); + $info->course = format_string($course->fullname,true); + $info->certificate = format_string($certificate->name,true); + $info->url = $CFG->wwwroot.'/mod/certificate/report.php?id='.$cm->id; + $from = $USER; + $postsubject = $strawarded . ': ' . $info->student . ' -> ' . $certificate->name; + $posttext = certificate_email_teachers_text($info); + $posthtml = ($teacher->mailformat == 1) ? certificate_email_teachers_html($info) : ''; + + @email_to_user($teacher, $from, $postsubject, $posttext, $posthtml); // If it fails, oh well, too bad. + } + } +} + +/** + * Alerts others by email of received certificates. First checks + * whether the option to email others is set for this certificate. + * Uses the email_teachers info. + * Code suggested by Eloy Lafuente + * + * @param stdClass $course + * @param stdClass $certificate + * @param stdClass $certrecord + * @param stdClass $cm course module + */ +function certificate_email_others($course, $certificate, $certrecord, $cm) { + global $USER, $CFG; + + if ($certificate->emailothers) { + $others = explode(',', $certificate->emailothers); + if ($others) { + $strawarded = get_string('awarded', 'certificate'); + foreach ($others as $other) { + $other = trim($other); + if (validate_email($other)) { + $destination = new stdClass; + $destination->id = 1; + $destination->email = $other; + $info = new stdClass; + $info->student = fullname($USER); + $info->course = format_string($course->fullname, true); + $info->certificate = format_string($certificate->name, true); + $info->url = $CFG->wwwroot.'/mod/certificate/report.php?id='.$cm->id; + $from = $USER; + $postsubject = $strawarded . ': ' . $info->student . ' -> ' . $certificate->name; + $posttext = certificate_email_teachers_text($info); + $posthtml = certificate_email_teachers_html($info); + + @email_to_user($destination, $from, $postsubject, $posttext, $posthtml); // If it fails, oh well, too bad. + } + } + } + } +} + +/** + * Creates the text content for emails to teachers -- needs to be finished with cron + * + * @param $info object The info used by the 'emailteachermail' language string + * @return string + */ +function certificate_email_teachers_text($info) { + $posttext = get_string('emailteachermail', 'certificate', $info) . "\n"; + + return $posttext; +} + +/** + * Creates the html content for emails to teachers + * + * @param $info object The info used by the 'emailteachermailhtml' language string + * @return string + */ +function certificate_email_teachers_html($info) { + $posthtml = ''; + $posthtml .= '

' . get_string('emailteachermailhtml', 'certificate', $info) . '

'; + $posthtml .= '
'; + + return $posthtml; +} + +/** + * Sends the student their issued certificate from moddata as an email + * attachment. + * + * @param stdClass $course + * @param stdClass $certificate + * @param stdClass $certrecord + * @param stdClass $context + * @param string $filecontents the PDF file contents + * @param string $filename + * @return bool Returns true if mail was sent OK and false if there was an error. + */ +function certificate_email_student($course, $certificate, $certrecord, $context, $filecontents, $filename) { + global $USER; + + // Get teachers + if ($users = get_users_by_capability($context, 'moodle/course:update', 'u.*', 'u.id ASC', + '', '', '', '', false, true)) { + $users = sort_by_roleassignment_authority($users, $context); + $teacher = array_shift($users); + } + + // If we haven't found a teacher yet, look for a non-editing teacher in this course. + if (empty($teacher) && $users = get_users_by_capability($context, 'moodle/course:update', 'u.*', 'u.id ASC', + '', '', '', '', false, true)) { + $users = sort_by_roleassignment_authority($users, $context); + $teacher = array_shift($users); + } + + // Ok, no teachers, use administrator name + if (empty($teacher)) { + $teacher = fullname(get_admin()); + } + + $info = new stdClass; + $info->username = fullname($USER); + $info->certificate = format_string($certificate->name, true); + $info->course = format_string($course->fullname, true); + $from = fullname($teacher); + $subject = $info->course . ': ' . $info->certificate; + $message = get_string('emailstudenttext', 'certificate', $info) . "\n"; + + // Make the HTML version more XHTML happy (&) + $messagehtml = text_to_html(get_string('emailstudenttext', 'certificate', $info)); + + $tempdir = make_temp_directory('certificate/attachment'); + if (!$tempdir) { + return false; + } + + $tempfile = $tempdir.'/'.md5(sesskey().microtime().$USER->id.'.pdf'); + $fp = fopen($tempfile, 'w+'); + fputs($fp, $filecontents); + fclose($fp); + + $prevabort = ignore_user_abort(true); + $result = email_to_user($USER, $from, $subject, $message, $messagehtml, $tempfile, $filename); + @unlink($tempfile); + ignore_user_abort($prevabort); + + return $result; +} + +/** + * This function returns success or failure of file save + * + * @param string $pdf is the string contents of the pdf + * @param int $certrecordid the certificate issue record id + * @param string $filename pdf filename + * @param int $contextid context id + * @return bool return true if successful, false otherwise + */ +function certificate_save_pdf($pdf, $certrecordid, $filename, $contextid) { + global $USER; + + if (empty($certrecordid)) { + return false; + } + + if (empty($pdf)) { + return false; + } + + $fs = get_file_storage(); + + // Prepare file record object + $component = 'mod_certificate'; + $filearea = 'issue'; + $filepath = '/'; + $fileinfo = array( + 'contextid' => $contextid, // ID of context + 'component' => $component, // usually = table name + 'filearea' => $filearea, // usually = table name + 'itemid' => $certrecordid, // usually = ID of row in table + 'filepath' => $filepath, // any path beginning and ending in / + 'filename' => $filename, // any filename + 'mimetype' => 'application/pdf', // any filename + 'userid' => $USER->id); + + // We do not know the previous file name, better delete everything here, + // luckily there is supposed to be always only one certificate here. + $fs->delete_area_files($contextid, $component, $filearea, $certrecordid); + + $fs->create_file_from_string($fileinfo, $pdf); + + return true; +} + +/** + * Produces a list of links to the issued certificates. Used for report. + * + * @param stdClass $certificate + * @param int $userid + * @param int $contextid + * @return string return the user files + */ +function certificate_print_user_files($certificate, $userid, $contextid) { + global $CFG, $DB, $OUTPUT; + + $output = ''; + + $certrecord = $DB->get_record('certificate_issues', array('userid' => $userid, 'certificateid' => $certificate->id)); + $fs = get_file_storage(); + + $component = 'mod_certificate'; + $filearea = 'issue'; + $files = $fs->get_area_files($contextid, $component, $filearea, $certrecord->id); + foreach ($files as $file) { + $filename = $file->get_filename(); + $link = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$contextid.'/mod_certificate/issue/'.$certrecord->id.'/'.$filename); + + $output = ''.$file->get_mimetype().' '. + ''.s($filename).''; + + } + $output .= '
'; + $output = '
'.$output.'
'; + + return $output; +} + +/** + * Inserts preliminary user data when a certificate is viewed. + * Prevents form from issuing a certificate upon browser refresh. + * + * @param stdClass $course + * @param stdClass $user + * @param stdClass $certificate + * @param stdClass $cm + * @return stdClass the newly created certificate issue + */ +function certificate_get_issue($course, $user, $certificate, $cm) { + global $DB; + + // Check if there is an issue already, should only ever be one + if ($certissue = $DB->get_record('certificate_issues', array('userid' => $user->id, 'certificateid' => $certificate->id))) { + return $certissue; + } + + // Create new certificate issue record + $certissue = new stdClass(); + $certissue->certificateid = $certificate->id; + $certissue->userid = $user->id; + $certissue->code = certificate_generate_code(); + $certissue->timecreated = time(); + $certissue->id = $DB->insert_record('certificate_issues', $certissue); + + // Email to the teachers and anyone else + certificate_email_teachers($course, $certificate, $certissue, $cm); + certificate_email_others($course, $certificate, $certissue, $cm); + + return $certissue; +} + +/** + * Returns a list of issued certificates - sorted for report. + * + * @param int $certificateid + * @param string $sort the sort order + * @param bool $groupmode are we in group mode ? + * @param stdClass $cm the course module + * @param int $page offset + * @param int $perpage total per page + * @return stdClass the users + */ +function certificate_get_issues($certificateid, $sort="ci.timecreated ASC", $groupmode, $cm, $page = 0, $perpage = 0) { + global $DB, $USER; + + $context = context_module::instance($cm->id); + $conditionssql = ''; + $conditionsparams = array(); + + // Get all users that can manage this certificate to exclude them from the report. + $certmanagers = array_keys(get_users_by_capability($context, 'mod/certificate:manage', 'u.id')); + $certmanagers = array_merge($certmanagers, array_keys(get_admins())); + list($sql, $params) = $DB->get_in_or_equal($certmanagers, SQL_PARAMS_NAMED, 'cert'); + $conditionssql .= "AND NOT u.id $sql \n"; + $conditionsparams += $params; + + if ($groupmode) { + $canaccessallgroups = has_capability('moodle/site:accessallgroups', $context); + $currentgroup = groups_get_activity_group($cm); + + // If we are viewing all participants and the user does not have access to all groups then return nothing. + if (!$currentgroup && !$canaccessallgroups) { + return array(); + } + + if ($currentgroup) { + if (!$canaccessallgroups) { + // Guest users do not belong to any groups. + if (isguestuser()) { + return array(); + } + + // Check that the user belongs to the group we are viewing. + $usersgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid); + if ($usersgroups) { + if (!isset($usersgroups[$currentgroup])) { + return array(); + } + } else { // They belong to no group, so return an empty array. + return array(); + } + } + + $groupusers = array_keys(groups_get_members($currentgroup, 'u.*')); + if (empty($groupusers)) { + return array(); + } + + list($sql, $params) = $DB->get_in_or_equal($groupusers, SQL_PARAMS_NAMED, 'grp'); + $conditionssql .= "AND u.id $sql "; + $conditionsparams += $params; + } + } + + $page = (int) $page; + $perpage = (int) $perpage; + + // Get all the users that have certificates issued, should only be one issue per user for a certificate + $allparams = $conditionsparams + array('certificateid' => $certificateid); + + // The picture fields also include the name fields for the user. + $picturefields = user_picture::fields('u', get_extra_user_fields($context)); + $users = $DB->get_records_sql("SELECT $picturefields, u.idnumber, ci.code, ci.timecreated + FROM {user} u + INNER JOIN {certificate_issues} ci + ON u.id = ci.userid + WHERE u.deleted = 0 + AND ci.certificateid = :certificateid $conditionssql + ORDER BY {$sort}", $allparams, $page * $perpage, $perpage); + + return $users; +} + +/** + * Returns a list of previously issued certificates--used for reissue. + * + * @param int $certificateid + * @return stdClass the attempts else false if none found + */ +function certificate_get_attempts($certificateid) { + global $DB, $USER; + + $sql = "SELECT * + FROM {certificate_issues} i + WHERE certificateid = :certificateid + AND userid = :userid"; + if ($issues = $DB->get_records_sql($sql, array('certificateid' => $certificateid, 'userid' => $USER->id))) { + return $issues; + } + + return false; +} + +/** + * Prints a table of previously issued certificates--used for reissue. + * + * @param stdClass $course + * @param stdClass $certificate + * @param stdClass $attempts + * @return string the attempt table + */ +function certificate_print_attempts($course, $certificate, $attempts) { + global $OUTPUT; + + echo $OUTPUT->heading(get_string('summaryofattempts', 'certificate')); + + // Prepare table header + $table = new html_table(); + $table->class = 'generaltable'; + $table->head = array(get_string('issued', 'certificate')); + $table->align = array('left'); + $table->attributes = array("style" => "width:20%; margin:auto"); + $gradecolumn = $certificate->printgrade; + if ($gradecolumn) { + $table->head[] = get_string('grade'); + $table->align[] = 'center'; + $table->size[] = ''; + } + // One row for each attempt + foreach ($attempts as $attempt) { + $row = array(); + + // prepare strings for time taken and date completed + $datecompleted = userdate($attempt->timecreated); + $row[] = $datecompleted; + + if ($gradecolumn) { + $attemptgrade = certificate_get_grade($certificate, $course); + $row[] = $attemptgrade; + } + + $table->data[$attempt->id] = $row; + } + + echo html_writer::table($table); +} + +/** + * Get the time the user has spent in the course + * + * @param int $courseid + * @return int the total time spent in seconds + */ +function certificate_get_course_time($courseid) { + global $CFG, $DB, $USER; + + $logmanager = get_log_manager(); + $readers = $logmanager->get_readers(); + $enabledreaders = get_config('tool_log', 'enabled_stores'); + $enabledreaders = explode(',', $enabledreaders); + + // Go through all the readers until we find one that we can use. + foreach ($enabledreaders as $enabledreader) { + $reader = $readers[$enabledreader]; + if ($reader instanceof \logstore_legacy\log\store) { + $logtable = 'log'; + $coursefield = 'course'; + $timefield = 'time'; + break; + } else if ($reader instanceof \core\log\sql_internal_table_reader) { + $logtable = $reader->get_internal_log_table_name(); + $coursefield = 'courseid'; + $timefield = 'timecreated'; + break; + } + } + + // If we didn't find a reader then return 0. + if (!isset($logtable)) { + return 0; + } + + $sql = "SELECT id, $timefield + FROM {{$logtable}} + WHERE userid = :userid + AND $coursefield = :courseid + ORDER BY $timefield ASC"; + $params = array('userid' => $USER->id, 'courseid' => $courseid); + + $totaltime = 0; + if ($logs = $DB->get_recordset_sql($sql, $params)) { + foreach ($logs as $log) { + if (!isset($login)) { + // For the first time $login is not set so the first log is also the first login + $login = $log->$timefield; + $lasthit = $log->$timefield; + $totaltime = 0; + } + $delay = $log->$timefield - $lasthit; + if ($delay > ($CFG->sessiontimeout * 60)) { + // The difference between the last log and the current log is more than + // the timeout Register session value so that we have found a session! + $login = $log->$timefield; + } else { + $totaltime += $delay; + } + // Now the actual log became the previous log for the next cycle + $lasthit = $log->$timefield; + } + + return $totaltime; + } + + return 0; +} + +/** + * Get all the modules + * + * @return array + */ +function certificate_get_mods() { + global $COURSE, $DB; + + $strtopic = get_string("topic"); + $strweek = get_string("week"); + $strsection = get_string("section"); + + // Collect modules data + $modinfo = get_fast_modinfo($COURSE); + $mods = $modinfo->get_cms(); + + $modules = array(); + $sections = $modinfo->get_section_info_all(); + for ($i = 0; $i <= count($sections) - 1; $i++) { + // should always be true + if (isset($sections[$i])) { + $section = $sections[$i]; + if ($section->sequence) { + switch ($COURSE->format) { + case "topics": + $sectionlabel = $strtopic; + break; + case "weeks": + $sectionlabel = $strweek; + break; + default: + $sectionlabel = $strsection; + } + + $sectionmods = explode(",", $section->sequence); + foreach ($sectionmods as $sectionmod) { + if (empty($mods[$sectionmod])) { + continue; + } + $mod = $mods[$sectionmod]; + $instance = $DB->get_record($mod->modname, array('id' => $mod->instance)); + if ($grade_items = grade_get_grade_items_for_activity($mod)) { + $mod_item = grade_get_grades($COURSE->id, 'mod', $mod->modname, $mod->instance); + $item = reset($mod_item->items); + if (isset($item->grademax)){ + $modules[$mod->id] = $sectionlabel . ' ' . $section->section . ' : ' . $instance->name; + } + } + } + } + } + } + + return $modules; +} + +/** + * Search through all the modules for grade data for mod_form. + * + * @return array + */ +function certificate_get_grade_options() { + $gradeoptions['0'] = get_string('no'); + $gradeoptions['1'] = get_string('coursegrade', 'certificate'); + + return $gradeoptions; +} + +/** + * Search through all the modules for grade dates for mod_form. + * + * @return array + */ +function certificate_get_date_options() { + $dateoptions['0'] = get_string('no'); + $dateoptions['1'] = get_string('issueddate', 'certificate'); + $dateoptions['2'] = get_string('completiondate', 'certificate'); + + return $dateoptions; +} + +/** + * Fetch all grade categories from the specified course. + * + * @param int $courseid the course id + * @return array + */ +function certificate_get_grade_categories($courseid) { + $grade_category_options = array(); + + if ($grade_categories = grade_category::fetch_all(array('courseid' => $courseid))) { + foreach ($grade_categories as $grade_category) { + if (!$grade_category->is_course_category()) { + $grade_category_options[-$grade_category->id] = get_string('category') . ' : ' . $grade_category->get_name(); + } + } + } + + return $grade_category_options; +} + +/** + * Get the course outcomes for for mod_form print outcome. + * + * @return array + */ +function certificate_get_outcomes() { + global $COURSE; + + // get all outcomes in course + $grade_seq = new grade_tree($COURSE->id, false, true, '', false); + if ($grade_items = $grade_seq->items) { + // list of item for menu + $printoutcome = array(); + foreach ($grade_items as $grade_item) { + if (isset($grade_item->outcomeid)){ + $itemmodule = $grade_item->itemmodule; + $printoutcome[$grade_item->id] = $itemmodule . ': ' . $grade_item->get_name(); + } + } + } + if (isset($printoutcome)) { + $outcomeoptions['0'] = get_string('no'); + foreach ($printoutcome as $key => $value) { + $outcomeoptions[$key] = $value; + } + } else { + $outcomeoptions['0'] = get_string('nooutcomes', 'certificate'); + } + + return $outcomeoptions; +} + + +/** + * Get certificate types indexed and sorted by name for mod_form. + * + * @return array containing the certificate type + */ +function certificate_types() { + $types = array(); + $names = get_list_of_plugins('mod/certificate/type'); + $sm = get_string_manager(); + foreach ($names as $name) { + if ($sm->string_exists('type'.$name, 'certificate')) { + $types[$name] = get_string('type'.$name, 'certificate'); + } else { + $types[$name] = ucfirst($name); + } + } + asort($types); + return $types; +} + +/** + * Get images for mod_form. + * + * @param string $type the image type + * @return array + */ +function certificate_get_images($type) { + global $CFG; + + switch($type) { + case CERT_IMAGE_BORDER : + $path = "$CFG->dirroot/mod/certificate/pix/borders"; + $uploadpath = "$CFG->dataroot/mod/certificate/pix/borders"; + break; + case CERT_IMAGE_SEAL : + $path = "$CFG->dirroot/mod/certificate/pix/seals"; + $uploadpath = "$CFG->dataroot/mod/certificate/pix/seals"; + break; + case CERT_IMAGE_SIGNATURE : + $path = "$CFG->dirroot/mod/certificate/pix/signatures"; + $uploadpath = "$CFG->dataroot/mod/certificate/pix/signatures"; + break; + case CERT_IMAGE_WATERMARK : + $path = "$CFG->dirroot/mod/certificate/pix/watermarks"; + $uploadpath = "$CFG->dataroot/mod/certificate/pix/watermarks"; + break; + } + // If valid path + if (!empty($path)) { + $options = array(); + $options += certificate_scan_image_dir($path); + $options += certificate_scan_image_dir($uploadpath); + + // Sort images + ksort($options); + + // Add the 'no' option to the top of the array + $options = array_merge(array('0' => get_string('no')), $options); + + return $options; + } else { + return array(); + } +} + +/** + * Prepare to print an activity grade. + * + * @param stdClass $course + * @param int $moduleid + * @param int $userid + * @return stdClass|bool return the mod object if it exists, false otherwise + */ +function certificate_get_mod_grade($course, $moduleid, $userid) { + global $DB; + + $cm = $DB->get_record('course_modules', array('id' => $moduleid)); + $module = $DB->get_record('modules', array('id' => $cm->module)); + + $grade_item = grade_get_grades($course->id, 'mod', $module->name, $cm->instance, $userid); + if (!empty($grade_item)) { + $item = new grade_item(); + $itemproperties = reset($grade_item->items); + foreach ($itemproperties as $key => $value) { + $item->$key = $value; + } + $modinfo = new stdClass; + $modname = $DB->get_field($module->name, 'name', array('id' => $cm->instance)); + $modinfo->name = format_string($modname, true, array('context' => context_module::instance($cm->id))); + $grade = $item->grades[$userid]->grade; + $item->gradetype = GRADE_TYPE_VALUE; + $item->courseid = $course->id; + + $modinfo->points = grade_format_gradevalue($grade, $item, true, GRADE_DISPLAY_TYPE_REAL, $decimals = 2); + $modinfo->percentage = grade_format_gradevalue($grade, $item, true, GRADE_DISPLAY_TYPE_PERCENTAGE, $decimals = 2); + $modinfo->letter = grade_format_gradevalue($grade, $item, true, GRADE_DISPLAY_TYPE_LETTER, $decimals = 0); + + if ($grade) { + $modinfo->dategraded = $item->grades[$userid]->dategraded; + } else { + $modinfo->dategraded = time(); + } + return $modinfo; + } + + return false; +} + +/** + * Returns the date to display for the certificate. + * + * @param stdClass $certificate + * @param stdClass $certrecord + * @param stdClass $course + * @param int $userid + * @return string the date + */ +function certificate_get_date($certificate, $certrecord, $course, $userid = null) { + global $DB, $USER; + + if (empty($userid)) { + $userid = $USER->id; + } + + // Set certificate date to current time, can be overwritten later + $date = $certrecord->timecreated; + + if ($certificate->printdate == '2') { + // Get the enrolment end date + $sql = "SELECT MAX(c.timecompleted) as timecompleted + FROM {course_completions} c + WHERE c.userid = :userid + AND c.course = :courseid"; + if ($timecompleted = $DB->get_record_sql($sql, array('userid' => $userid, 'courseid' => $course->id))) { + if (!empty($timecompleted->timecompleted)) { + $date = $timecompleted->timecompleted; + } + } + } else if ($certificate->printdate > 2) { + if ($modinfo = certificate_get_mod_grade($course, $certificate->printdate, $userid)) { + $date = $modinfo->dategraded; + } + } + if ($certificate->printdate > 0) { + if ($certificate->datefmt == 1) { + $certificatedate = userdate($date, '%B %d, %Y'); + } else if ($certificate->datefmt == 2) { + $suffix = certificate_get_ordinal_number_suffix(userdate($date, '%d')); + $certificatedate = userdate($date, '%B %d' . $suffix . ', %Y'); + } else if ($certificate->datefmt == 3) { + $certificatedate = userdate($date, '%d de %B de %Y'); + } else if ($certificate->datefmt == 4) { + $certificatedate = userdate($date, '%B %Y'); + } else if ($certificate->datefmt == 5) { + $certificatedate = userdate($date, get_string('strftimedate', 'langconfig')); + } + + return $certificatedate; + } + + return ''; +} + +/** + * Helper function to return the suffix of the day of + * the month, eg 'st' if it is the 1st of the month. + * + * @param int the day of the month + * @return string the suffix. + */ +function certificate_get_ordinal_number_suffix($day) { + if (!in_array(($day % 100), array(11, 12, 13))) { + switch ($day % 10) { + // Handle 1st, 2nd, 3rd + case 1: return 'st'; + case 2: return 'nd'; + case 3: return 'rd'; + } + } + return 'th'; +} + +/** + * Returns the grade to display for the certificate. + * + * @param stdClass $certificate + * @param stdClass $course + * @param int $userid + * @param bool $valueonly if true return only the points, %age, or letter with no prefix + * @return string the grade result + */ +function certificate_get_grade($certificate, $course, $userid = null, $valueonly = false) { + global $USER; + + if (empty($userid)) { + $userid = $USER->id; + } + + if ($certificate->printgrade > 0) { + if ($certificate->printgrade == 1) { + if ($course_item = grade_item::fetch_course_item($course->id)) { + // Check we want to add a prefix to the grade. + $strprefix = ''; + if (!$valueonly) { + $strprefix = get_string('coursegrade', 'certificate') . ': '; + } + + $grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $userid)); + $course_item->gradetype = GRADE_TYPE_VALUE; + $coursegrade = new stdClass; + $coursegrade->points = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_REAL, $decimals = 2); + $coursegrade->percentage = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE, $decimals = 2); + $coursegrade->letter = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_LETTER, $decimals = 0); + + if ($certificate->gradefmt == 1) { + $grade = $strprefix . $coursegrade->percentage; + } else if ($certificate->gradefmt == 2) { + $grade = $strprefix . $coursegrade->points; + } else if ($certificate->gradefmt == 3) { + $grade = $strprefix . $coursegrade->letter; + } + + return $grade; + } + } else { // Print the mod grade + if ($modinfo = certificate_get_mod_grade($course, $certificate->printgrade, $userid)) { + // Check we want to add a prefix to the grade. + $strprefix = ''; + if (!$valueonly) { + $strprefix = $modinfo->name . ' ' . get_string('grade', 'certificate') . ': '; + } + if ($certificate->gradefmt == 1) { + $grade = $strprefix . $modinfo->percentage; + } else if ($certificate->gradefmt == 2) { + $grade = $strprefix . $modinfo->points; + } else if ($certificate->gradefmt == 3) { + $grade = $strprefix . $modinfo->letter; + } + + return $grade; + } + } + } else if ($certificate->printgrade < 0) { // Must be a category id. + if ($category_item = grade_item::fetch(array('itemtype' => 'category', 'iteminstance' => -$certificate->printgrade))) { + $category_item->gradetype = GRADE_TYPE_VALUE; + + $grade = new grade_grade(array('itemid' => $category_item->id, 'userid' => $userid)); + + $category_grade = new stdClass; + $category_grade->points = grade_format_gradevalue($grade->finalgrade, $category_item, true, GRADE_DISPLAY_TYPE_REAL, $decimals = 2); + $category_grade->percentage = grade_format_gradevalue($grade->finalgrade, $category_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE, $decimals = 2); + $category_grade->letter = grade_format_gradevalue($grade->finalgrade, $category_item, true, GRADE_DISPLAY_TYPE_LETTER, $decimals = 0); + + if ($certificate->gradefmt == 1) { + $formattedgrade = $category_grade->percentage; + } else if ($certificate->gradefmt == 2) { + $formattedgrade = $category_grade->points; + } else if ($certificate->gradefmt == 3) { + $formattedgrade = $category_grade->letter; + } + + return $formattedgrade; + } + } + + return ''; +} + +/** + * Returns the outcome to display on the certificate + * + * @param stdClass $certificate + * @param stdClass $course + * @return string the outcome + */ +function certificate_get_outcome($certificate, $course) { + global $USER; + + if ($certificate->printoutcome > 0) { + if ($grade_item = new grade_item(array('id' => $certificate->printoutcome))) { + $outcomeinfo = new stdClass; + $outcomeinfo->name = $grade_item->get_name(); + $outcome = new grade_grade(array('itemid' => $grade_item->id, 'userid' => $USER->id)); + $outcomeinfo->grade = grade_format_gradevalue($outcome->finalgrade, $grade_item, true, GRADE_DISPLAY_TYPE_REAL); + + return $outcomeinfo->name . ': ' . $outcomeinfo->grade; + } + } + + return ''; +} + +/** + * Returns the code to display on the certificate. + * + * @param stdClass $certificate + * @param stdClass $certrecord + * @return string the code + */ +function certificate_get_code($certificate, $certrecord) { + if ($certificate->printnumber) { + return $certrecord->code; + } + + return ''; +} + +/** + * Sends text to output given the following params. + * + * @param stdClass $pdf + * @param int $x horizontal position + * @param int $y vertical position + * @param char $align L=left, C=center, R=right + * @param string $font any available font in font directory + * @param char $style ''=normal, B=bold, I=italic, U=underline + * @param int $size font size in points + * @param string $text the text to print + * @param int $width horizontal dimension of text block + */ +function certificate_print_text($pdf, $x, $y, $align, $font='freeserif', $style, $size = 10, $text, $width = 0) { + $pdf->setFont($font, $style, $size); + $pdf->SetXY($x, $y); + $pdf->writeHTMLCell($width, 0, '', '', $text, 0, 0, 0, true, $align); +} + +/** + * Creates rectangles for line border for A4 size paper. + * + * @param stdClass $pdf + * @param stdClass $certificate + */ +function certificate_draw_frame($pdf, $certificate) { + if ($certificate->bordercolor > 0) { + if ($certificate->bordercolor == 1) { + $color = array(0, 0, 0); // black + } + if ($certificate->bordercolor == 2) { + $color = array(153, 102, 51); // brown + } + if ($certificate->bordercolor == 3) { + $color = array(0, 51, 204); // blue + } + if ($certificate->bordercolor == 4) { + $color = array(0, 180, 0); // green + } + switch ($certificate->orientation) { + case 'L': + // create outer line border in selected color + $pdf->SetLineStyle(array('width' => 1.5, 'color' => $color)); + $pdf->Rect(10, 10, 277, 190); + // create middle line border in selected color + $pdf->SetLineStyle(array('width' => 0.2, 'color' => $color)); + $pdf->Rect(13, 13, 271, 184); + // create inner line border in selected color + $pdf->SetLineStyle(array('width' => 1.0, 'color' => $color)); + $pdf->Rect(16, 16, 265, 178); + break; + case 'P': + // create outer line border in selected color + $pdf->SetLineStyle(array('width' => 1.5, 'color' => $color)); + $pdf->Rect(10, 10, 190, 277); + // create middle line border in selected color + $pdf->SetLineStyle(array('width' => 0.2, 'color' => $color)); + $pdf->Rect(13, 13, 184, 271); + // create inner line border in selected color + $pdf->SetLineStyle(array('width' => 1.0, 'color' => $color)); + $pdf->Rect(16, 16, 178, 265); + break; + } + } +} + +/** + * Creates rectangles for line border for letter size paper. + * + * @param stdClass $pdf + * @param stdClass $certificate + */ +function certificate_draw_frame_letter($pdf, $certificate) { + if ($certificate->bordercolor > 0) { + if ($certificate->bordercolor == 1) { + $color = array(0, 0, 0); //black + } + if ($certificate->bordercolor == 2) { + $color = array(153, 102, 51); //brown + } + if ($certificate->bordercolor == 3) { + $color = array(0, 51, 204); //blue + } + if ($certificate->bordercolor == 4) { + $color = array(0, 180, 0); //green + } + switch ($certificate->orientation) { + case 'L': + // create outer line border in selected color + $pdf->SetLineStyle(array('width' => 4.25, 'color' => $color)); + $pdf->Rect(28, 28, 736, 556); + // create middle line border in selected color + $pdf->SetLineStyle(array('width' => 0.2, 'color' => $color)); + $pdf->Rect(37, 37, 718, 538); + // create inner line border in selected color + $pdf->SetLineStyle(array('width' => 2.8, 'color' => $color)); + $pdf->Rect(46, 46, 700, 520); + break; + case 'P': + // create outer line border in selected color + $pdf->SetLineStyle(array('width' => 1.5, 'color' => $color)); + $pdf->Rect(25, 20, 561, 751); + // create middle line border in selected color + $pdf->SetLineStyle(array('width' => 0.2, 'color' => $color)); + $pdf->Rect(40, 35, 531, 721); + // create inner line border in selected color + $pdf->SetLineStyle(array('width' => 1.0, 'color' => $color)); + $pdf->Rect(51, 46, 509, 699); + break; + } + } +} + +/** + * Prints border images from the borders folder in PNG or JPG formats. + * + * @param stdClass $pdf + * @param stdClass $certificate + * @param string $type the type of image + * @param int $x x position + * @param int $y y position + * @param int $w the width + * @param int $h the height + */ +function certificate_print_image($pdf, $certificate, $type, $x, $y, $w, $h) { + global $CFG; + + switch($type) { + case CERT_IMAGE_BORDER : + $attr = 'borderstyle'; + $path = "$CFG->dirroot/mod/certificate/pix/$type/$certificate->borderstyle"; + $uploadpath = "$CFG->dataroot/mod/certificate/pix/$type/$certificate->borderstyle"; + break; + case CERT_IMAGE_SEAL : + $attr = 'printseal'; + $path = "$CFG->dirroot/mod/certificate/pix/$type/$certificate->printseal"; + $uploadpath = "$CFG->dataroot/mod/certificate/pix/$type/$certificate->printseal"; + break; + case CERT_IMAGE_SIGNATURE : + $attr = 'printsignature'; + $path = "$CFG->dirroot/mod/certificate/pix/$type/$certificate->printsignature"; + $uploadpath = "$CFG->dataroot/mod/certificate/pix/$type/$certificate->printsignature"; + break; + case CERT_IMAGE_WATERMARK : + $attr = 'printwmark'; + $path = "$CFG->dirroot/mod/certificate/pix/$type/$certificate->printwmark"; + $uploadpath = "$CFG->dataroot/mod/certificate/pix/$type/$certificate->printwmark"; + break; + } + // Has to be valid + if (!empty($path)) { + switch ($certificate->$attr) { + case '0' : + case '' : + break; + default : + if (file_exists($path)) { + $pdf->Image($path, $x, $y, $w, $h); + } + if (file_exists($uploadpath)) { + $pdf->Image($uploadpath, $x, $y, $w, $h); + } + break; + } + } +} + + +function custom_random_string($length=15) { + $pool = 'ABCDEFGHJKMNOPQRSTUVWXYZ'; + $pool .= 'abcdefghjkmnopqrstuvwxyz'; + $pool .= '0123456789'; + $poollen = strlen($pool); + $string = ''; + for($i=0; $i < $length; $i++) { + $string .= substr($pool, (mt_rand()%($poollen)), 1); + } + return $string; + } + +/** + * Generates a 10-digit code of random letters and numbers. + * + * @return string + */ +function certificate_generate_code() { + global $DB; + + $uniquecodefound = false; + $code = custom_random_string(10); + while (!$uniquecodefound) { + if (!$DB->record_exists('certificate_issues', array('code' => $code))) { + $uniquecodefound = true; + } else { + $code = custom_random_string(10); + } + } + + return $code; +} + +/** + * Scans directory for valid images + * + * @param string the path + * @return array + */ +function certificate_scan_image_dir($path) { + // Array to store the images + $options = array(); + + // Start to scan directory + if (is_dir($path)) { + $iterator = new DirectoryIterator($path); + foreach ($iterator as $fileinfo) { + $filename = $fileinfo->getFilename(); + $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + if ($fileinfo->isFile() && in_array($extension, array('png', 'jpg', 'jpeg'))) { + $options[$filename] = pathinfo($filename, PATHINFO_FILENAME); + } + } + } + return $options; +} + +/** + * Get normalised certificate file name without file extension. + * + * @param stdClass $certificate + * @param stdClass $cm + * @param stdClass $course + * @return string file name without extension + */ +function certificate_get_certificate_filename($certificate, $cm, $course) { + $coursecontext = context_course::instance($course->id); + $coursename = format_string($course->shortname, true, array('context' => $coursecontext)); + + $context = context_module::instance($cm->id); + $name = format_string($certificate->name, true, array('context' => $context)); + + $filename = $coursename . '_' . $name; + $filename = core_text::entities_to_utf8($filename); + $filename = strip_tags($filename); + $filename = rtrim($filename, '.'); + + // Ampersand is not a valid filename char, let's replace it with something else. + $filename = str_replace('&', '_', $filename); + + $filename = clean_filename($filename); + + if (empty($filename)) { + // This is weird, but we need some file name. + $filename = 'certificate'; + } + + return $filename; +} diff --git a/mobile/mod_certificate.zip b/mobile/mod_certificate.zip new file mode 100644 index 0000000..3e7aaff Binary files /dev/null and b/mobile/mod_certificate.zip differ diff --git a/mod_form.php b/mod_form.php index 5d7c227..44ad1a6 100644 --- a/mod_form.php +++ b/mod_form.php @@ -18,8 +18,7 @@ /** * Instance add/edit form * -* @package mod -* @subpackage certificate +* @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -29,7 +28,7 @@ if (!defined('MOODLE_INTERNAL')) { } require_once ($CFG->dirroot.'/course/moodleform_mod.php'); -require_once($CFG->dirroot.'/mod/certificate/lib.php'); +require_once($CFG->dirroot.'/mod/certificate/locallib.php'); class mod_certificate_mod_form extends moodleform_mod { @@ -48,7 +47,7 @@ class mod_certificate_mod_form extends moodleform_mod { } $mform->addRule('name', null, 'required', null, 'client'); - $this->add_intro_editor(false, get_string('intro', 'certificate')); + $this->standard_intro_elements(get_string('intro', 'certificate')); // Issue options $mform->addElement('header', 'issueoptions', get_string('issueoptions', 'certificate')); @@ -136,7 +135,7 @@ class mod_certificate_mod_form extends moodleform_mod { $orientation = array( 'L' => get_string('landscape', 'certificate'), 'P' => get_string('portrait', 'certificate')); $mform->addElement('select', 'orientation', get_string('orientation', 'certificate'), $orientation); - $mform->setDefault('orientation', 'landscape'); + $mform->setDefault('orientation', 'L'); $mform->addHelpButton('orientation', 'orientation', 'certificate'); $mform->addElement('select', 'borderstyle', get_string('borderstyle', 'certificate'), certificate_get_images(CERT_IMAGE_BORDER)); @@ -183,4 +182,4 @@ class mod_certificate_mod_form extends moodleform_mod { return $errors; } -} \ No newline at end of file +} diff --git a/report.php b/report.php index 553aca2..755f31c 100644 --- a/report.php +++ b/report.php @@ -18,14 +18,13 @@ /** * Handles viewing the report * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once('../../config.php'); -require_once('lib.php'); +require_once('locallib.php'); $id = required_param('id', PARAM_INT); // Course module ID $sort = optional_param('sort', '', PARAM_RAW); @@ -67,7 +66,7 @@ if (!$certificate = $DB->get_record('certificate', array('id'=> $cm->instance))) } // Requires a course login -require_course_login($course->id, false, $cm); +require_login($course, false, $cm); // Check capabilities $context = context_module::instance($cm->id); @@ -96,22 +95,23 @@ if (!$download) { $page = $perpage = 0; } -add_to_log($course->id, 'certificate', 'view', "report.php?id=$cm->id", '$certificate->id', $cm->id); - // Ensure there are issues to display, if not display notice if (!$users = certificate_get_issues($certificate->id, $DB->sql_fullname(), $groupmode, $cm, $page, $perpage)) { echo $OUTPUT->header(); groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/certificate/report.php?id='.$id); - notify(get_string('nocertificatesissued', 'certificate')); + echo $OUTPUT->notification(get_string('nocertificatesissued', 'certificate')); echo $OUTPUT->footer($course); exit(); } +// Get extra fields to show the user. +$extrafields = get_extra_user_fields($context); + if ($download == "ods") { require_once("$CFG->libdir/odslib.class.php"); // Calculate file name - $filename = clean_filename("$course->shortname " . rtrim($certificate->name, '.') . '.ods'); + $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.ods'; // Creating a workbook $workbook = new MoodleODSWorkbook("-"); // Send HTTP headers @@ -122,11 +122,15 @@ if ($download == "ods") { // Print names of all the fields $myxls->write_string(0, 0, get_string("lastname")); $myxls->write_string(0, 1, get_string("firstname")); - $myxls->write_string(0, 2, get_string("idnumber")); - $myxls->write_string(0, 3, get_string("group")); - $myxls->write_string(0, 4, $strdate); - $myxls->write_string(0, 5, $strgrade); - $myxls->write_string(0, 6, $strcode); + $nextposition = 2; + foreach ($extrafields as $field) { + $myxls->write_string(0, $nextposition, get_user_field_name($field)); + $nextposition++; + } + $myxls->write_string(0, $nextposition, get_string("group")); + $myxls->write_string(0, $nextposition + 1, $strdate); + $myxls->write_string(0, $nextposition + 2, $strgrade); + $myxls->write_string(0, $nextposition + 3, $strcode); // Generate the data for the body of the spreadsheet $i = 0; @@ -135,18 +139,21 @@ if ($download == "ods") { foreach ($users as $user) { $myxls->write_string($row, 0, $user->lastname); $myxls->write_string($row, 1, $user->firstname); - $studentid = (!empty($user->idnumber)) ? $user->idnumber : " "; - $myxls->write_string($row, 2, $studentid); + $nextposition = 2; + foreach ($extrafields as $field) { + $myxls->write_string($row, $nextposition, $user->$field); + $nextposition++; + } $ug2 = ''; if ($usergrps = groups_get_all_groups($course->id, $user->id)) { foreach ($usergrps as $ug) { $ug2 = $ug2. $ug->name; } } - $myxls->write_string($row, 3, $ug2); - $myxls->write_string($row, 4, userdate($user->timecreated)); - $myxls->write_string($row, 5, certificate_get_grade($certificate, $course, $user->id)); - $myxls->write_string($row, 6, $user->code); + $myxls->write_string($row, $nextposition, $ug2); + $myxls->write_string($row, $nextposition + 1, userdate($user->timecreated)); + $myxls->write_string($row, $nextposition + 2, certificate_get_grade($certificate, $course, $user->id)); + $myxls->write_string($row, $nextposition + 3, $user->code); $row++; } $pos = 6; @@ -160,7 +167,7 @@ if ($download == "xls") { require_once("$CFG->libdir/excellib.class.php"); // Calculate file name - $filename = clean_filename("$course->shortname " . rtrim($certificate->name, '.') . '.xls'); + $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.xls'; // Creating a workbook $workbook = new MoodleExcelWorkbook("-"); // Send HTTP headers @@ -171,11 +178,15 @@ if ($download == "xls") { // Print names of all the fields $myxls->write_string(0, 0, get_string("lastname")); $myxls->write_string(0, 1, get_string("firstname")); - $myxls->write_string(0, 2, get_string("idnumber")); - $myxls->write_string(0, 3, get_string("group")); - $myxls->write_string(0, 4, $strdate); - $myxls->write_string(0, 5, $strgrade); - $myxls->write_string(0, 6, $strcode); + $nextposition = 2; + foreach ($extrafields as $field) { + $myxls->write_string(0, $nextposition, get_user_field_name($field)); + $nextposition++; + } + $myxls->write_string(0, $nextposition, get_string("group")); + $myxls->write_string(0, $nextposition + 1, $strdate); + $myxls->write_string(0, $nextposition + 2, $strgrade); + $myxls->write_string(0, $nextposition + 3, $strcode); // Generate the data for the body of the spreadsheet $i = 0; @@ -184,18 +195,21 @@ if ($download == "xls") { foreach ($users as $user) { $myxls->write_string($row, 0, $user->lastname); $myxls->write_string($row, 1, $user->firstname); - $studentid = (!empty($user->idnumber)) ? $user->idnumber : " "; - $myxls->write_string($row,2,$studentid); + $nextposition = 2; + foreach ($extrafields as $field) { + $myxls->write_string($row, $nextposition, $user->$field); + $nextposition++; + } $ug2 = ''; if ($usergrps = groups_get_all_groups($course->id, $user->id)) { foreach ($usergrps as $ug) { $ug2 = $ug2 . $ug->name; } } - $myxls->write_string($row, 3, $ug2); - $myxls->write_string($row, 4, userdate($user->timecreated)); - $myxls->write_string($row, 5, certificate_get_grade($certificate, $course, $user->id)); - $myxls->write_string($row, 6, $user->code); + $myxls->write_string($row, $nextposition, $ug2); + $myxls->write_string($row, $nextposition + 1, userdate($user->timecreated)); + $myxls->write_string($row, $nextposition + 2, certificate_get_grade($certificate, $course, $user->id)); + $myxls->write_string($row, $nextposition + 3, $user->code); $row++; } $pos = 6; @@ -206,7 +220,7 @@ if ($download == "xls") { } if ($download == "txt") { - $filename = clean_filename("$course->shortname " . rtrim($certificate->name, '.') . '.txt'); + $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.txt'; header("Content-Type: application/download\n"); header("Content-Disposition: attachment; filename=\"$filename\""); @@ -215,7 +229,10 @@ if ($download == "txt") { header("Pragma: public"); // Print names of all the fields - echo get_string("lastname"). "\t" .get_string("firstname") . "\t". get_string("idnumber") . "\t"; + echo get_string("lastname"). "\t" .get_string("firstname") . "\t"; + foreach ($extrafields as $field) { + echo get_user_field_name($field) . "\t"; + } echo get_string("group"). "\t"; echo $strdate. "\t"; echo $strgrade. "\t"; @@ -226,12 +243,10 @@ if ($download == "txt") { $row=1; if ($users) foreach ($users as $user) { echo $user->lastname; - echo "\t" . $user->firstname; - $studentid = " "; - if (!empty($user->idnumber)) { - $studentid = $user->idnumber; + echo "\t" . $user->firstname . "\t"; + foreach ($extrafields as $field) { + echo $user->$field . "\t"; } - echo "\t" . $studentid . "\t"; $ug2 = ''; if ($usergrps = groups_get_all_groups($course->id, $user->id)) { foreach ($usergrps as $ug) { @@ -253,13 +268,25 @@ $usercount = count(certificate_get_issues($certificate->id, $DB->sql_fullname(), $table = new html_table(); $table->width = "95%"; $table->tablealign = "center"; -$table->head = array($strto, $strdate, $strgrade, $strcode); -$table->align = array("left", "left", "center", "center"); +$table->head = array($strto); +$table->align = array('left'); +foreach ($extrafields as $field) { + $table->head[] = get_user_field_name($field); + $table->align[] = 'left'; +} +$table->head = array_merge($table->head, array($strdate, $strgrade, $strcode)); +$table->align = array_merge($table->align, array('left', 'center', 'center')); foreach ($users as $user) { $name = $OUTPUT->user_picture($user) . fullname($user); $date = userdate($user->timecreated) . certificate_print_user_files($certificate, $user->id, $context->id); $code = $user->code; - $table->data[] = array ($name, $date, certificate_get_grade($certificate, $course, $user->id), $code); + $data = array(); + $data[] = $name; + foreach ($extrafields as $field) { + $data[] = $user->$field; + } + $data = array_merge($data, array($date, certificate_get_grade($certificate, $course, $user->id), $code)); + $table->data[] = $data; } // Create table to store buttons diff --git a/review.php b/review.php index 40d8d7f..37ff2d1 100644 --- a/review.php +++ b/review.php @@ -18,14 +18,13 @@ /** * This page reviews a certificate * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once('../../config.php'); -require_once('lib.php'); +require_once('locallib.php'); require_once("$CFG->libdir/pdflib.php"); // Retrieve any variables that are passed @@ -44,11 +43,12 @@ if (!$certificate = $DB->get_record('certificate', array('id'=> $cm->instance))) print_error('course module is incorrect'); } -// Requires login -require_login(); +// Requires a course login +require_login($course, true, $cm); // Check the capabilities $context = context_module::instance($cm->id); +//require_capability('mod/certificate:view', $context); // Initialize $PAGE, compute blocks $PAGE->set_url('/mod/certificate/review.php', array('id' => $cm->id)); @@ -67,17 +67,22 @@ if (!$certrecord = $DB->get_record('certificate_issues', array('userid' => $USER require ("$CFG->dirroot/mod/certificate/type/$certificate->certificatetype/certificate.php"); if ($action) { - // Remove full-stop at the end if it exists, to avoid "..pdf" being created and being filtered by clean_filename - $certname = rtrim($certificate->name, '.'); - $filename = clean_filename("$certname.pdf"); - $pdf->Output($filename, 'I'); // open in browser + $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.pdf'; + $filecontents = $pdf->Output('', 'S'); + // Open in browser. + send_file($filecontents, $filename, 0, 0, true, false, 'application/pdf'); exit(); } echo $OUTPUT->header(); +$reviewurl = new moodle_url('/mod/certificate/review.php', array('id' => $cm->id)); +groups_print_activity_menu($cm, $reviewurl); +$currentgroup = groups_get_activity_group($cm); +$groupmode = groups_get_activity_groupmode($cm); + if (has_capability('mod/certificate:manage', $context)) { - $numusers = count(certificate_get_issues($certificate->id, 'ci.timecreated ASC', '', $cm)); + $numusers = count(certificate_get_issues($certificate->id, 'ci.timecreated ASC', $groupmode, $cm)); $url = html_writer::tag('a', get_string('viewcertificateviews', 'certificate', $numusers), array('href' => $CFG->wwwroot . '/mod/certificate/report.php?id=' . $cm->id)); echo html_writer::tag('div', $url, array('class' => 'reportlink')); diff --git a/settings.php b/settings.php index c5ca962..a5ebee4 100644 --- a/settings.php +++ b/settings.php @@ -18,17 +18,22 @@ /** * Provides some custom settings for the certificate module * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Michael Avelar * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die; -require_once($CFG->dirroot.'/mod/certificate/adminsetting.class.php'); +if ($ADMIN->fulltree) { -$settings->add(new mod_certificate_admin_setting_upload('certificate/uploadimage', - get_string('uploadimage', 'certificate'), get_string('uploadimagedesc', 'certificate'), '')); + $settings->add(new mod_certificate_admin_setting_upload('certificate/uploadimage', + get_string('uploadimage', 'mod_certificate'), get_string('uploadimagedesc', 'certificate'), '')); -?> \ No newline at end of file + $settings->add(new mod_certificate_admin_setting_font('certificate/fontsans', + get_string('fontsans', 'mod_certificate'), get_string('fontsans_desc', 'mod_certificate'), 'freesans')); + + $settings->add(new mod_certificate_admin_setting_font('certificate/fontserif', + get_string('fontserif', 'mod_certificate'), get_string('fontserif_desc', 'mod_certificate'), 'freeserif')); + +} diff --git a/tests/generator/lib.php b/tests/generator/lib.php new file mode 100644 index 0000000..513d8a7 --- /dev/null +++ b/tests/generator/lib.php @@ -0,0 +1,91 @@ +. + +/** + * Certificate module data generator. + * + * @package mod_certificate + * @category test + * @author Russell England + * @copyright Catalyst IT Ltd 2013 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL + */ + +defined('MOODLE_INTERNAL') || die(); + +class mod_certificate_generator extends testing_module_generator { + + /** + * Create new certificate module instance + * @param array|stdClass $record data for module being generated. Requires 'course' key + * (an id or the full object). Also can have any fields from add module form. + * @param null|array $options general options for course module. Since 2.6 it is + * possible to omit this argument by merging options into $record + * @return stdClass record from module-defined table with additional field + * cmid (corresponding id in course_modules table) + */ + public function create_instance($record = null, array $options = null) { + global $CFG; + require_once("$CFG->dirroot/mod/certificate/lib.php"); + + $this->instancecount++; + $i = $this->instancecount; + + $record = (object)(array)$record; + $options = (array)$options; + + if (empty($record->course)) { + throw new coding_exception('module generator requires $record->course'); + } + + $defaults = array(); + $defaults['name'] = get_string('pluginname', 'certificate').' '.$i; + $defaults['intro'] = 'Test certificate '.$i; + $defaults['introformat'] = FORMAT_MOODLE; + $defaults['emailteachers'] = 0; + $defaults['savecert'] = 0; + $defaults['reportcert'] = 0; + $defaults['delivery'] = 0; + $defaults['certificatetype'] = 'A4_non_embedded'; + $defaults['orientation'] = 'L'; + $defaults['borderstyle'] = '0'; + $defaults['bordercolor'] = '0'; + $defaults['printwmark'] = '0'; + $defaults['printdate'] = 0; + $defaults['datefmt'] = 0; + $defaults['printnumber'] = 0; + $defaults['printgrade'] = 0; + $defaults['gradefmt'] = 0; + $defaults['printoutcome'] = 0; + $defaults['printhours'] = ''; + $defaults['printteacher'] = 0; + $defaults['printsignature'] = '0'; + $defaults['printseal'] = '0'; + foreach ($defaults as $field => $value) { + if (!isset($record->$field)) { + $record->$field = $value; + } + } + + if (isset($options['idnumber'])) { + $record->cmidnumber = $options['idnumber']; + } else { + $record->cmidnumber = ''; + } + + // Do work to actually add the instance. + return parent::create_instance($record, (array)$options); + } +} diff --git a/tests/generator_test.php b/tests/generator_test.php new file mode 100644 index 0000000..2596093 --- /dev/null +++ b/tests/generator_test.php @@ -0,0 +1,56 @@ +. + +/** + * Certificate module data generator. + * + * @package mod_certificate + * @category test + * @author Russell England + * @copyright Catalyst IT Ltd 2013 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL + */ + +defined('MOODLE_INTERNAL') || die(); + +class mod_certificate_generator_testcase extends advanced_testcase { + public function test_generator() { + global $DB; + + $this->resetAfterTest(true); + + $this->assertEquals(0, $DB->count_records('certificate')); + + $course = $this->getDataGenerator()->create_course(); + + /** @var mod_certificate_generator $generator */ + $generator = $this->getDataGenerator()->get_plugin_generator('mod_certificate'); + $this->assertInstanceOf('mod_certificate_generator', $generator); + $this->assertEquals('certificate', $generator->get_modulename()); + + $generator->create_instance(array('course' => $course->id)); + $generator->create_instance(array('course' => $course->id)); + $certificate = $generator->create_instance(array('course' => $course->id)); + $this->assertEquals(3, $DB->count_records('certificate')); + + $cm = get_coursemodule_from_instance('certificate', $certificate->id); + $this->assertEquals($certificate->id, $cm->instance); + $this->assertEquals('certificate', $cm->modname); + $this->assertEquals($course->id, $cm->course); + + $context = context_module::instance($cm->id); + $this->assertEquals($certificate->cmid, $context->instanceid); + } +} diff --git a/type/A4_embedded/certificate.php b/type/A4_embedded/certificate.php index d95af58..d3c69dc 100644 --- a/type/A4_embedded/certificate.php +++ b/type/A4_embedded/certificate.php @@ -18,15 +18,12 @@ /** * A4_embedded certificate type * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -if (!defined('MOODLE_INTERNAL')) { - die('Direct access to this script is forbidden.'); // It must be included from view.php -} +defined('MOODLE_INTERNAL') || die(); $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); @@ -77,6 +74,10 @@ if ($certificate->orientation == 'L') { $codey = 250; } +// Get font families. +$fontsans = get_config('certificate', 'fontsans'); +$fontserif = get_config('certificate', 'fontserif'); + // Add images and lines certificate_print_image($pdf, $certificate, CERT_IMAGE_BORDER, $brdrx, $brdry, $brdrw, $brdrh); certificate_draw_frame($pdf, $certificate); @@ -89,29 +90,28 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, // Add text $pdf->SetTextColor(0, 0, 120); -certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 30, get_string('title', 'certificate')); +certificate_print_text($pdf, $x, $y, 'C', $fontsans, '', 30, get_string('title', 'certificate')); $pdf->SetTextColor(0, 0, 0); -certificate_print_text($pdf, $x, $y + 20, 'C', 'freeserif', '', 20, get_string('certify', 'certificate')); -certificate_print_text($pdf, $x, $y + 36, 'C', 'freesans', '', 30, fullname($USER)); -certificate_print_text($pdf, $x, $y + 55, 'C', 'freesans', '', 20, get_string('statement', 'certificate')); -certificate_print_text($pdf, $x, $y + 72, 'C', 'freesans', '', 20, $course->fullname); -certificate_print_text($pdf, $x, $y + 92, 'C', 'freesans', '', 14, certificate_get_date($certificate, $certrecord, $course)); -certificate_print_text($pdf, $x, $y + 102, 'C', 'freeserif', '', 10, certificate_get_grade($certificate, $course)); -certificate_print_text($pdf, $x, $y + 112, 'C', 'freeserif', '', 10, certificate_get_outcome($certificate, $course)); +certificate_print_text($pdf, $x, $y + 20, 'C', $fontserif, '', 20, get_string('certify', 'certificate')); +certificate_print_text($pdf, $x, $y + 36, 'C', $fontsans, '', 30, fullname($USER)); +certificate_print_text($pdf, $x, $y + 55, 'C', $fontsans, '', 20, get_string('statement', 'certificate')); +certificate_print_text($pdf, $x, $y + 72, 'C', $fontsans, '', 20, format_string($course->fullname)); +certificate_print_text($pdf, $x, $y + 92, 'C', $fontsans, '', 14, certificate_get_date($certificate, $certrecord, $course)); +certificate_print_text($pdf, $x, $y + 102, 'C', $fontserif, '', 10, certificate_get_grade($certificate, $course)); +certificate_print_text($pdf, $x, $y + 112, 'C', $fontserif, '', 10, certificate_get_outcome($certificate, $course)); if ($certificate->printhours) { - certificate_print_text($pdf, $x, $y + 122, 'C', 'freeserif', '', 10, get_string('credithours', 'certificate') . ': ' . $certificate->printhours); + certificate_print_text($pdf, $x, $y + 122, 'C', $fontserif, '', 10, get_string('credithours', 'certificate') . ': ' . $certificate->printhours); } -certificate_print_text($pdf, $x, $codey, 'C', 'freeserif', '', 10, certificate_get_code($certificate, $certrecord)); +certificate_print_text($pdf, $x, $codey, 'C', $fontserif, '', 10, certificate_get_code($certificate, $certrecord)); $i = 0; if ($certificate->printteacher) { $context = context_module::instance($cm->id); if ($teachers = get_users_by_capability($context, 'mod/certificate:printteacher', '', $sort = 'u.lastname ASC', '', '', '', '', false)) { foreach ($teachers as $teacher) { $i++; - certificate_print_text($pdf, $sigx, $sigy + ($i * 4), 'L', 'freeserif', '', 12, fullname($teacher)); + certificate_print_text($pdf, $sigx, $sigy + ($i * 4), 'L', $fontserif, '', 12, fullname($teacher)); } } } certificate_print_text($pdf, $custx, $custy, 'L', null, null, null, $certificate->customtext); -?> \ No newline at end of file diff --git a/type/A4_non_embedded/certificate.php b/type/A4_non_embedded/certificate.php index 7bdc7d4..80722c4 100644 --- a/type/A4_non_embedded/certificate.php +++ b/type/A4_non_embedded/certificate.php @@ -18,15 +18,12 @@ /** * A4_non_embedded certificate type * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -if (!defined('MOODLE_INTERNAL')) { - die('Direct access to this script is forbidden.'); // It must be included from view.php -} +defined('MOODLE_INTERNAL') || die(); $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); @@ -94,7 +91,7 @@ $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y + 20, 'C', 'Times', '', 20, get_string('certify', 'certificate')); certificate_print_text($pdf, $x, $y + 36, 'C', 'Helvetica', '', 30, fullname($USER)); certificate_print_text($pdf, $x, $y + 55, 'C', 'Helvetica', '', 20, get_string('statement', 'certificate')); -certificate_print_text($pdf, $x, $y + 72, 'C', 'Helvetica', '', 20, $course->fullname); +certificate_print_text($pdf, $x, $y + 72, 'C', 'Helvetica', '', 20, format_string($course->fullname)); certificate_print_text($pdf, $x, $y + 92, 'C', 'Helvetica', '', 14, certificate_get_date($certificate, $certrecord, $course)); certificate_print_text($pdf, $x, $y + 102, 'C', 'Times', '', 10, certificate_get_grade($certificate, $course)); certificate_print_text($pdf, $x, $y + 112, 'C', 'Times', '', 10, certificate_get_outcome($certificate, $course)); @@ -114,4 +111,3 @@ if ($certificate->printteacher) { } certificate_print_text($pdf, $custx, $custy, 'L', null, null, null, $certificate->customtext); -?> \ No newline at end of file diff --git a/type/ILB_Com_tutoria/certificate.php b/type/ILB_Com_tutoria/certificate.php new file mode 100644 index 0000000..bd9c493 --- /dev/null +++ b/type/ILB_Com_tutoria/certificate.php @@ -0,0 +1,182 @@ +. + +/** + * A4_embedded certificate type + * + * @package mod + * @subpackage certificate + * @copyright Mark Nelson + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +if (!defined('MOODLE_INTERNAL')) { + die('Direct access to this script is forbidden.'); // It must be included from view.php +} + +/** + * Gets the course start date (for ILB start date is the date of enrollment) + * and completion date from course completion framework. + * Finally format them to print + */ +require_once("$CFG->dirroot/completion/completion_completion.php"); + +$start_date = $course->startdate; +$end_date = $course->enddate; +$emissao_date = $course->enddate; + +$fmt = '%d/%m/%Y'; // Default format +if ($certificate->datefmt == 1) { + $fmt = '%B %d, %Y'; +} else if ($certificate->datefmt == 2) { + $suffix = certificate_get_ordinal_number_suffix(userdate($ts, '%d')); + $fmt = '%B %d' . $suffix . ', %Y'; +} else if ($certificate->datefmt == 3) { + $fmt = '%d de %B de %Y'; +} else if ($certificate->datefmt == 4) { + $fmt = '%B de %Y'; +} else if ($certificate->datefmt == 5) { + $fmt = get_string('strftimedate', 'langconfig'); +} + +$start_date = userdate($start_date, $fmt); +$end_date = userdate($end_date, $fmt); +$emissao_date = userdate($emissao_date, $fmt); + +//MASK para CPF +function mask($val, $mask) +{ + $maskared = ''; + $k = 0; + for($i = 0; $i<=strlen($mask)-1; $i++){ + + if($mask[$i] == '#'){ + if(isset($val[$k])) + $maskared .= $val[$k++]; + } + else + { + if(isset($mask[$i])) + $maskared .= $mask[$i]; + } + } +return $maskared; +} + +$cpf = mask($USER->username, '###.###.###-##'); + +require_once($CFG->dirroot.'/user/profile/field/cpf/field.class.php'); + + +$pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); + +$pdf->SetTitle($certificate->name); +$pdf->SetProtection(array('modify')); +$pdf->setPrintHeader(false); +$pdf->setPrintFooter(false); +$pdf->SetAutoPageBreak(false, 0); +$pdf->AddPage(); + +// Define variables +// Landscape +if ($certificate->orientation == 'L') { + $x = 20; + $y = 60; + $sealx = 230; + $sealy = 150; + $sigx = 00; + $sigy = 165; + $custx = 15; + $custy = $y+25; + $wmarkx = 40; + $wmarky = 31; + $wmarkw = 212; + $wmarkh = 148; + $brdrx = 0; + $brdry = 0; + $brdrw = 297; + $brdrh = 210; + $codex = $x; + $codey = 175; +} else { // Portrait + $x = 10; + $y = 90; + $sealx = 150; + $sealy = 220; + $sigx = 10; + $sigy = 235; + $custx = 15; + $custy = $y+25; + $wmarkx = 26; + $wmarky = 58; + $wmarkw = 158; + $wmarkh = 170; + $brdrx = 0; + $brdry = 0; + $brdrw = 210; + $brdrh = 297; + $codex = $x; + $codey = 245; +} + +// Front page ------------------------------------------------------------------------------------------------------------ +// Add images and lines +certificate_print_image($pdf, $certificate, CERT_IMAGE_BORDER, $brdrx, $brdry, $brdrw, $brdrh); +certificate_draw_frame($pdf, $certificate); +// Set alpha to semi-transparency +$pdf->SetAlpha(0.2); +certificate_print_image($pdf, $certificate, CERT_IMAGE_WATERMARK, $wmarkx, $wmarky, $wmarkw, $wmarkh); +$pdf->SetAlpha(1); +certificate_print_image($pdf, $certificate, CERT_IMAGE_SEAL, $sealx, $sealy, '', ''); +certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, '', ''); + +// Add text +$pdf->SetTextColor(0, 0, 0); +certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, get_string('title', 'certificate')); +certificate_print_text($pdf, $x, $y + 15, 'C', 'freesans', '', 18, get_string('certify', 'certificate')); +certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº $cpf"); +certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', '', 18, "realizou, na modalidade a distância, o curso com tutoria"); +certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', 'B', 18, mb_strtoupper($course->fullname, 'UTF-8')); +certificate_print_text($pdf, $x, $y + 55, 'C', 'freesans', '', 18, "no período de {$start_date} a {$end_date}"); +if ($certificate->printhours) { + certificate_print_text($pdf, $x, $y + 65, 'C', 'freesans', '', 18, "com carga horária de {$certificate->printhours}"); +} +certificate_print_text($pdf, $x, $y + 75, 'C', 'freesans', '', 18, certificate_get_grade($certificate, $course)); +certificate_print_text($pdf, $x, $y + 85, 'R', 'freesans', 'B', 14, "Brasília, {$emissao_date}."); + + +// Verse page ----------------------------------------------------------------------------------------------------------- +$pdf->AddPage(); +// Add images and lines +certificate_print_image($pdf, $certificate, CERT_IMAGE_BORDER, $brdrx, $brdry, $brdrw, $brdrh); +certificate_draw_frame($pdf, $certificate); +// Set alpha to semi-transparency +$pdf->SetAlpha(0.2); +certificate_print_image($pdf, $certificate, CERT_IMAGE_WATERMARK, $wmarkx, $wmarky, $wmarkw, $wmarkh); +$pdf->SetAlpha(1); +certificate_print_image($pdf, $certificate, CERT_IMAGE_SEAL, $sealx, $sealy, '', ''); + +// Add text +$pdf->SetTextColor(0, 0, 0); +certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, 'PROGRAMA DO CURSO'); +certificate_print_text($pdf, $x, $y + 10, 'C', 'freesans', '', 20, mb_strtoupper($course->fullname, 'UTF-8')); +certificate_print_text($pdf, $custx, $custy, 'L', 'freesans', '', 10, $certificate->customtext); +certificate_print_text($pdf, $codex, $codey, 'C', 'freesans', '', 10, 'CÓDIGO DE VALIDAÇÃO'); +certificate_print_text($pdf, $codex, $codey + 5, 'C', 'freesans', 'B', 12, certificate_get_code($certificate, $certrecord)); +certificate_print_text($pdf, $codex, $codey + 10, 'C', 'freesans', '', 10, 'Para verificar a autenticidade deste certificado, acesse http://saberes.senado.leg.br/ e informe o código acima'); + +?> diff --git a/type/ILB_Com_tutoria_2014/certificate.php b/type/ILB_Com_tutoria_2014/certificate.php index ab26987..491c713 100644 --- a/type/ILB_Com_tutoria_2014/certificate.php +++ b/type/ILB_Com_tutoria_2014/certificate.php @@ -57,6 +57,30 @@ $start_date = userdate($start_date, $fmt); $end_date = userdate($end_date, $fmt); $emissao_date = userdate($emissao_date, $fmt); +//MASK para CPF +function mask($val, $mask) +{ + $maskared = ''; + $k = 0; + for($i = 0; $i<=strlen($mask)-1; $i++){ + + if($mask[$i] == '#'){ + if(isset($val[$k])) + $maskared .= $val[$k++]; + } + else + { + if(isset($mask[$i])) + $maskared .= $mask[$i]; + } + } +return $maskared; +} + +$cpf = mask($USER->username, '###.###.###-##'); + +require_once($CFG->dirroot.'/user/profile/field/cpf/field.class.php'); + $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); @@ -124,7 +148,7 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, get_string('title', 'certificate')); certificate_print_text($pdf, $x, $y + 15, 'C', 'freesans', '', 18, get_string('certify', 'certificate')); -certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº {$USER->profile['cpf']},"); +certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº $cpf"); certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', '', 18, "realizou, na modalidade a distância, o curso com tutoria"); certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', 'B', 18, mb_strtoupper($course->fullname, 'UTF-8')); certificate_print_text($pdf, $x, $y + 55, 'C', 'freesans', '', 18, "no período de {$start_date} a {$end_date}"); diff --git a/type/ILB_Sem_tutoria_2014/certificate.php b/type/ILB_Sem_tutoria_2014/certificate.php index 610739f..1388105 100644 --- a/type/ILB_Sem_tutoria_2014/certificate.php +++ b/type/ILB_Sem_tutoria_2014/certificate.php @@ -59,6 +59,30 @@ if ($certificate->datefmt == 1) { $start_date = userdate($start_date, $fmt); $end_date = userdate($end_date, $fmt); +//MASK para CPF +function mask($val, $mask) +{ + $maskared = ''; + $k = 0; + for($i = 0; $i<=strlen($mask)-1; $i++){ + + if($mask[$i] == '#'){ + if(isset($val[$k])) + $maskared .= $val[$k++]; + } + else + { + if(isset($mask[$i])) + $maskared .= $mask[$i]; + } + } +return $maskared; +} + +$cpf = mask($USER->username, '###.###.###-##'); + +require_once($CFG->dirroot.'/user/profile/field/cpf/field.class.php'); + $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); $pdf->SetTitle($certificate->name); @@ -125,7 +149,7 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, get_string('title', 'certificate')); certificate_print_text($pdf, $x, $y + 15, 'C', 'freesans', '', 18, get_string('certify', 'certificate')); -certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº {$USER->profile['cpf']}"); +certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº $cpf"); certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', '', 18, "realizou, na modalidade a distância, o curso sem tutoria"); certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', 'B', 18, mb_strtoupper($course->fullname, 'UTF-8')); certificate_print_text($pdf, $x, $y + 55, 'C', 'freesans', '', 18, "no período de {$start_date} a {$end_date}"); diff --git a/type/ILB_presencial_2016/certificate.php b/type/ILB_presencial_2016/certificate.php index f481e3e..61cd2b1 100644 --- a/type/ILB_presencial_2016/certificate.php +++ b/type/ILB_presencial_2016/certificate.php @@ -55,6 +55,31 @@ if ($certificate->datefmt == 1) { $start_date = userdate($start_date, $fmt); $end_date = userdate($end_date, $fmt); +//MASK para CPF +function mask($val, $mask) +{ + $maskared = ''; + $k = 0; + for($i = 0; $i<=strlen($mask)-1; $i++){ + + if($mask[$i] == '#'){ + if(isset($val[$k])) + $maskared .= $val[$k++]; + } + else + { + if(isset($mask[$i])) + $maskared .= $mask[$i]; + } + } +return $maskared; +} + +$cpf = mask($USER->username, '###.###.###-##'); + +require_once($CFG->dirroot.'/user/profile/field/cpf/field.class.php'); + + $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); $pdf->SetTitle($certificate->name); @@ -121,7 +146,7 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, get_string('title', 'certificate')); certificate_print_text($pdf, $x, $y + 15, 'C', 'freesans', '', 18, get_string('certify', 'certificate')); -certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº {$USER->profile['cpf']}"); +certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº $cpf"); certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', '', 18, "realizou, na modalidade presencial, o curso"); certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', 'B', 18, mb_strtoupper($course->fullname, 'UTF-8')); certificate_print_text($pdf, $x, $y + 55, 'C', 'freesans', '', 18, "no período de {$start_date} a {$end_date}"); diff --git a/type/Oficinas_Interlegis/certificate.php b/type/Oficinas_Interlegis/certificate.php index 721192e..acb4820 100644 --- a/type/Oficinas_Interlegis/certificate.php +++ b/type/Oficinas_Interlegis/certificate.php @@ -41,6 +41,32 @@ $style = << EOT */ + +//MASK para CPF +function mask($val, $mask) +{ + $maskared = ''; + $k = 0; + for($i = 0; $i<=strlen($mask)-1; $i++){ + + if($mask[$i] == '#'){ + if(isset($val[$k])) + $maskared .= $val[$k++]; + } + else + { + if(isset($mask[$i])) + $maskared .= $mask[$i]; + } + } +return $maskared; +} + +$cpf = mask($USER->username, '###.###.###-##'); + +require_once($CFG->dirroot.'/user/profile/field/cpf/field.class.php'); + + $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); $pdf->SetTitle($certificate->name); @@ -107,7 +133,7 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, get_string('title', 'certificate')); certificate_print_text($pdf, $x, $y + 15, 'C', 'freesans', '', 18, get_string('certify', 'certificate')); -certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº {$USER->profile['cpf']}"); +certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº $cpf"); certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', '', 18, "participou, na modalidade presencial, da oficina"); certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', 'B', 18, mb_strtoupper($course->fullname, 'UTF-8')); $tagvs = array('p' => array(0 => array('h' => 0, 'n' => 0), 1 => array('h' => 0, 'n'=> 0))); diff --git a/type/PFG_FC2/certificate.php b/type/PFG_FC2/certificate.php index 5e16dcb..3297b72 100644 --- a/type/PFG_FC2/certificate.php +++ b/type/PFG_FC2/certificate.php @@ -54,6 +54,13 @@ if ($certificate->datefmt == 1) { $start_date = userdate($start_date, $fmt); $end_date = userdate($end_date, $fmt); + +require_once($CFG->dirroot.'/user/profile/field/cpf/field.class.php'); +$formfield = new profile_field_cpf('8', $USER->id); +$cpf = $formfield->display_data(); + + + $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); $pdf->SetTitle($certificate->name); @@ -120,7 +127,7 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, get_string('title', 'certificate')); certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', '', 18, get_string('certify', 'certificate')); -certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº {$USER->profile['cpf']},"); +certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº $cpf"); certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', '', 18, "concluiu com aproveitamento o"); certificate_print_text($pdf, $x, $y + 55, 'C', 'freesans', 'B', 18, mb_strtoupper($course->fullname, 'UTF-8')); certificate_print_text($pdf, $x, $y + 65, 'C', 'freesans', '', 18, "com carga horária de 129 horas/aula."); diff --git a/type/PFG_FC2_2016/certificate.php b/type/PFG_FC2_2016/certificate.php index 45cf536..321fb73 100644 --- a/type/PFG_FC2_2016/certificate.php +++ b/type/PFG_FC2_2016/certificate.php @@ -54,6 +54,11 @@ if ($certificate->datefmt == 1) { $start_date = userdate($start_date, $fmt); $end_date = userdate($end_date, $fmt); +require_once($CFG->dirroot.'/user/profile/field/cpf/field.class.php'); +$formfield = new profile_field_cpf('8', $USER->id); +$cpf = $formfield->display_data(); + + $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); $pdf->SetTitle($certificate->name); @@ -120,7 +125,7 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, get_string('title', 'certificate')); certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', '', 18, get_string('certify', 'certificate')); -certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº {$USER->profile['cpf']},"); +certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº $cpf"); certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', '', 18, "concluiu com aproveitamento o"); certificate_print_text($pdf, $x, $y + 55, 'C', 'freesans', 'B', 18, mb_strtoupper($course->fullname, 'UTF-8')); certificate_print_text($pdf, $x, $y + 65, 'C', 'freesans', '', 18, "com carga horária de {$certificate->printhours}."); diff --git a/type/PFG_FC3/certificate.php b/type/PFG_FC3/certificate.php index 969b720..1e0b68c 100644 --- a/type/PFG_FC3/certificate.php +++ b/type/PFG_FC3/certificate.php @@ -54,6 +54,11 @@ if ($certificate->datefmt == 1) { $start_date = userdate($start_date, $fmt); $end_date = userdate($end_date, $fmt); +require_once($CFG->dirroot.'/user/profile/field/cpf/field.class.php'); +$formfield = new profile_field_cpf('8', $USER->id); +$cpf = $formfield->display_data(); + + $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); $pdf->SetTitle($certificate->name); @@ -120,7 +125,7 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, get_string('title', 'certificate')); certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', '', 18, get_string('certify', 'certificate')); -certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº {$USER->profile['cpf']},"); +certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº $cpf"); certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', '', 18, "concluiu com aproveitamento o"); certificate_print_text($pdf, $x, $y + 55, 'C', 'freesans', 'B', 18, mb_strtoupper($course->fullname, 'UTF-8')); certificate_print_text($pdf, $x, $y + 65, 'C', 'freesans', '', 18, "com carga horária de 86 horas/aula."); diff --git a/type/cert_comtutoria/certificate.php b/type/cert_comtutoria/certificate.php index 0eb49ba..a356101 100644 --- a/type/cert_comtutoria/certificate.php +++ b/type/cert_comtutoria/certificate.php @@ -41,6 +41,35 @@ $style = << EOT */ + + +//MASK para CPF +function mask($val, $mask) +{ + $maskared = ''; + $k = 0; + for($i = 0; $i<=strlen($mask)-1; $i++){ + + if($mask[$i] == '#'){ + if(isset($val[$k])) + $maskared .= $val[$k++]; + } + else + { + if(isset($mask[$i])) + $maskared .= $mask[$i]; + } + } +return $maskared; +} + +$cpf = mask($USER->username, '###.###.###-##'); + +require_once($CFG->dirroot.'/user/profile/field/cpf/field.class.php'); + + + + $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); $pdf->SetTitle($certificate->name); @@ -107,7 +136,7 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, get_string('title', 'certificate')); certificate_print_text($pdf, $x, $y + 15, 'C', 'freesans', '', 18, get_string('certify', 'certificate')); -certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº {$USER->profile['cpf']}"); +certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº $cpf"); certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', '', 18, "realizou, na modalidade a distância, ".certificate_get_grade($certificate, $course).','); certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', 'B', 18, 'o curso com tutoria '.mb_strtoupper($course->fullname, 'UTF-8')); $tagvs = array('p' => array(0 => array('h' => 0, 'n' => 0), 1 => array('h' => 0, 'n'=> 0))); diff --git a/type/cert_presencial/certificate.php b/type/cert_presencial/certificate.php index 396d80f..663b190 100644 --- a/type/cert_presencial/certificate.php +++ b/type/cert_presencial/certificate.php @@ -32,14 +32,29 @@ $group = end(groups_get_all_groups($course->id, $USER->id)); $group_name = format_string($group->name); $group_description = format_text($group->description, $group->descriptiontext); -#Obtem a nota do aluno, se o curso estiver configurado para gerar -#certificado com nota. Do contrário, o campo virá sempre em branco. -$grade=certificate_get_grade($certificate, $course); -if( $grade != '' ) { - #Se houver nota, acrescenta vírgulas antes e depois - $grade = $grade . ', '; +//MASK para CPF +function mask($val, $mask) +{ + $maskared = ''; + $k = 0; + for($i = 0; $i<=strlen($mask)-1; $i++){ + + if($mask[$i] == '#'){ + if(isset($val[$k])) + $maskared .= $val[$k++]; + } + else + { + if(isset($mask[$i])) + $maskared .= $mask[$i]; + } + } +return $maskared; } +$cpf = mask($USER->username, '###.###.###-##'); + +require_once($CFG->dirroot.'/user/profile/field/cpf/field.class.php'); /* $style = << EOT */ + + +#Obtem a nota do aluno, se o curso estiver configurado para gerar +#certificado com nota. Do contrário, o campo virá sempre em branco. +$grade=certificate_get_grade($certificate, $course); +if( $grade != '' ) { + #Se houver nota, acrescenta vírgulas antes e depois + $grade = $grade . ', '; +} + $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); $pdf->SetTitle($certificate->name); @@ -117,8 +142,9 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, get_string('title', 'certificate')); certificate_print_text($pdf, $x, $y + 15, 'C', 'freesans', '', 18, get_string('certify', 'certificate')); -certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº {$USER->profile['cpf']}"); -certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', '', 18, "realizou, na modalidade presencial, " . $grade . "o curso"); +//certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº {$USER->profile['cpf']}"); +certificate_print_text($pdf, $x, $y + 25, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº $cpf"); +certificate_print_text($pdf, $x, $y + 35, 'C', 'freesans', '', 18, "realizou, na modalidade presencial, ". $grade ."o curso"); certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', 'B', 18, mb_strtoupper($course->fullname, 'UTF-8')); $tagvs = array('p' => array(0 => array('h' => 0, 'n' => 0), 1 => array('h' => 0, 'n'=> 0))); $pdf->setHtmlVSpace($tagvs); diff --git a/type/cert_presencial_rasf/certificate.php b/type/cert_presencial_rasf/certificate.php index 59b721b..2d53b42 100644 --- a/type/cert_presencial_rasf/certificate.php +++ b/type/cert_presencial_rasf/certificate.php @@ -41,6 +41,32 @@ $style = << EOT */ + +//MASK para CPF +function mask($val, $mask) +{ + $maskared = ''; + $k = 0; + for($i = 0; $i<=strlen($mask)-1; $i++){ + + if($mask[$i] == '#'){ + if(isset($val[$k])) + $maskared .= $val[$k++]; + } + else + { + if(isset($mask[$i])) + $maskared .= $mask[$i]; + } + } +return $maskared; +} + +$cpf = mask($USER->username, '###.###.###-##'); + +require_once($CFG->dirroot.'/user/profile/field/cpf/field.class.php'); + + $pdf = new PDF($certificate->orientation, 'mm', 'A4', true, 'UTF-8', false); $pdf->SetTitle($certificate->name); @@ -107,7 +133,7 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 20, get_string('title', 'certificate')); certificate_print_text($pdf, $x, $y + 15, 'C', 'freesans', '', 18, get_string('certifyilb', 'certificate')); -certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº {$USER->profile['cpf']}"); +certificate_print_text($pdf, $x, $y + 45, 'C', 'freesans', 'B', 18, mb_strtoupper(fullname($USER), 'UTF-8').", CPF nº $cpf"); certificate_print_text($pdf, $x, $y + 55, 'C', 'freesans', '', 18, "realizou, na modalidade presencial, ".certificate_get_grade($certificate, $course).", o curso"); certificate_print_text($pdf, $x, $y + 65, 'C', 'freesans', 'B', 18, mb_strtoupper($course->fullname, 'UTF-8')); $tagvs = array('p' => array(0 => array('h' => 0, 'n' => 0), 1 => array('h' => 0, 'n'=> 0))); diff --git a/type/letter_embedded/certificate.php b/type/letter_embedded/certificate.php index c24b1a7..57f7c27 100644 --- a/type/letter_embedded/certificate.php +++ b/type/letter_embedded/certificate.php @@ -18,17 +18,14 @@ /** * letter_embedded certificate type * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -if (!defined('MOODLE_INTERNAL')) { - die('Direct access to this script is forbidden.'); // It must be included from view.php -} +defined('MOODLE_INTERNAL') || die(); -$pdf = new PDF($certificate->orientation, 'pt', 'Letter', true, 'UTF-8', false); +$pdf = new PDF($certificate->orientation, 'pt', 'LETTER', true, 'UTF-8', false); $pdf->SetTitle($certificate->name); $pdf->SetProtection(array('modify')); @@ -77,6 +74,10 @@ if ($certificate->orientation == 'L') { $codey = 660; } +// Get font families. +$fontsans = get_config('certificate', 'fontsans'); +$fontserif = get_config('certificate', 'fontserif'); + // Add images and lines certificate_print_image($pdf, $certificate, CERT_IMAGE_BORDER, $brdrx, $brdry, $brdrw, $brdrh); certificate_draw_frame_letter($pdf, $certificate); @@ -89,29 +90,28 @@ certificate_print_image($pdf, $certificate, CERT_IMAGE_SIGNATURE, $sigx, $sigy, // Add text $pdf->SetTextColor(0, 0, 120); -certificate_print_text($pdf, $x, $y, 'C', 'freesans', '', 30, get_string('title', 'certificate')); +certificate_print_text($pdf, $x, $y, 'C', $fontsans, '', 30, get_string('title', 'certificate')); $pdf->SetTextColor(0, 0, 0); -certificate_print_text($pdf, $x, $y + 55, 'C', 'freeserif', '', 20, get_string('certify', 'certificate')); -certificate_print_text($pdf, $x, $y + 105, 'C', 'freeserif', '', 30, fullname($USER)); -certificate_print_text($pdf, $x, $y + 155, 'C', 'freeserif', '', 20, get_string('statement', 'certificate')); -certificate_print_text($pdf, $x, $y + 205, 'C', 'freeserif', '', 20, $course->fullname); -certificate_print_text($pdf, $x, $y + 255, 'C', 'freeserif', '', 14, certificate_get_date($certificate, $certrecord, $course)); -certificate_print_text($pdf, $x, $y + 283, 'C', 'freeserif', '', 10, certificate_get_grade($certificate, $course)); -certificate_print_text($pdf, $x, $y + 311, 'C', 'freeserif', '', 10, certificate_get_outcome($certificate, $course)); +certificate_print_text($pdf, $x, $y + 55, 'C', $fontserif, '', 20, get_string('certify', 'certificate')); +certificate_print_text($pdf, $x, $y + 105, 'C', $fontserif, '', 30, fullname($USER)); +certificate_print_text($pdf, $x, $y + 155, 'C', $fontserif, '', 20, get_string('statement', 'certificate')); +certificate_print_text($pdf, $x, $y + 205, 'C', $fontserif, '', 20, format_string($course->fullname)); +certificate_print_text($pdf, $x, $y + 255, 'C', $fontserif, '', 14, certificate_get_date($certificate, $certrecord, $course)); +certificate_print_text($pdf, $x, $y + 283, 'C', $fontserif, '', 10, certificate_get_grade($certificate, $course)); +certificate_print_text($pdf, $x, $y + 311, 'C', $fontserif, '', 10, certificate_get_outcome($certificate, $course)); if ($certificate->printhours) { - certificate_print_text($pdf, $x, $y + 339, 'C', 'freeserif', '', 10, get_string('credithours', 'certificate') . ': ' . $certificate->printhours); + certificate_print_text($pdf, $x, $y + 339, 'C', $fontserif, '', 10, get_string('credithours', 'certificate') . ': ' . $certificate->printhours); } -certificate_print_text($pdf, $x, $codey, 'C', 'freeserif', '', 10, certificate_get_code($certificate, $certrecord)); +certificate_print_text($pdf, $x, $codey, 'C', $fontserif, '', 10, certificate_get_code($certificate, $certrecord)); $i = 0; if ($certificate->printteacher) { $context = context_module::instance($cm->id); if ($teachers = get_users_by_capability($context, 'mod/certificate:printteacher', '', $sort = 'u.lastname ASC', '', '', '', '', false)) { foreach ($teachers as $teacher) { $i++; - certificate_print_text($pdf, $sigx, $sigy + ($i * 12), 'L', 'freeserif', '', 12, fullname($teacher)); + certificate_print_text($pdf, $sigx, $sigy + ($i * 12), 'L', $fontserif, '', 12, fullname($teacher)); } } } certificate_print_text($pdf, $custx, $custy, 'L', null, null, null, $certificate->customtext); -?> \ No newline at end of file diff --git a/type/letter_non_embedded/certificate.php b/type/letter_non_embedded/certificate.php index 33b9635..88cdd40 100644 --- a/type/letter_non_embedded/certificate.php +++ b/type/letter_non_embedded/certificate.php @@ -18,17 +18,14 @@ /** * letter_non_embedded certificate type * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -if (!defined('MOODLE_INTERNAL')) { - die('Direct access to this script is forbidden.'); // It must be included from view.php -} +defined('MOODLE_INTERNAL') || die(); -$pdf = new PDF($certificate->orientation, 'pt', 'Letter', true, 'UTF-8', false); +$pdf = new PDF($certificate->orientation, 'pt', 'LETTER', true, 'UTF-8', false); $pdf->SetTitle($certificate->name); $pdf->SetProtection(array('modify')); @@ -94,7 +91,7 @@ $pdf->SetTextColor(0, 0, 0); certificate_print_text($pdf, $x, $y + 55, 'C', 'Times', '', 20, get_string('certify', 'certificate')); certificate_print_text($pdf, $x, $y + 105, 'C', 'Helvetica', '', 30, fullname($USER)); certificate_print_text($pdf, $x, $y + 155, 'C', 'Helvetica', '', 20, get_string('statement', 'certificate')); -certificate_print_text($pdf, $x, $y + 205, 'C', 'Helvetica', '', 20, $course->fullname); +certificate_print_text($pdf, $x, $y + 205, 'C', 'Helvetica', '', 20, format_string($course->fullname)); certificate_print_text($pdf, $x, $y + 255, 'C', 'Helvetica', '', 14, certificate_get_date($certificate, $certrecord, $course)); certificate_print_text($pdf, $x, $y + 283, 'C', 'Times', '', 10, certificate_get_grade($certificate, $course)); certificate_print_text($pdf, $x, $y + 311, 'C', 'Times', '', 10, certificate_get_outcome($certificate, $course)); @@ -114,4 +111,3 @@ if ($certificate->printteacher) { } certificate_print_text($pdf, $custx, $custy, 'L', null, null, null, $certificate->customtext); -?> \ No newline at end of file diff --git a/upload_image.php b/upload_image.php index c9811b3..1ef3963 100644 --- a/upload_image.php +++ b/upload_image.php @@ -18,14 +18,13 @@ /** * Handles uploading files * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require('../../config.php'); -require_once($CFG->dirroot.'/mod/certificate/lib.php'); +require_once($CFG->dirroot.'/mod/certificate/locallib.php'); require_once($CFG->dirroot.'/mod/certificate/upload_image_form.php'); require_login(); @@ -63,4 +62,3 @@ if ($upload_form->is_cancelled()) { echo $OUTPUT->header(); echo $upload_form->display(); echo $OUTPUT->footer(); -?> diff --git a/upload_image_form.php b/upload_image_form.php index e5977cd..0bf341b 100644 --- a/upload_image_form.php +++ b/upload_image_form.php @@ -18,8 +18,7 @@ /** * Handles uploading files * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -29,7 +28,7 @@ if (!defined('MOODLE_INTERNAL')) { } require_once($CFG->libdir.'/formslib.php'); -require_once($CFG->dirroot.'/mod/certificate/lib.php'); +require_once($CFG->dirroot.'/mod/certificate/locallib.php'); class mod_certificate_upload_image_form extends moodleform { @@ -81,4 +80,4 @@ class mod_certificate_upload_image_form extends moodleform { return $errors; } -} \ No newline at end of file +} diff --git a/version.php b/version.php index 8c98463..4284827 100644 --- a/version.php +++ b/version.php @@ -18,16 +18,17 @@ /** * Code fragment to define the version of the certificate module * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late */ -$module->version = 2013102300; // The current module version (Date: YYYYMMDDXX) -$module->requires = 2012120300; // Requires this Moodle version -$module->cron = 12 * 60 * 60; // Period for cron to check this module (secs) 12 hours -$module->component = 'mod_certificate'; +defined('MOODLE_INTERNAL') || die(); -$module->maturity = MATURITY_STABLE; -$module->release = "Stable"; // User-friendly version number +$plugin->version = 2018040201; // The current module version (Date: YYYYMMDDXX) +$plugin->requires = 2016052300; // Requires this Moodle version (3.1) +$plugin->cron = 12*60*20; // Period for cron to check this module (secs) +$plugin->component = 'mod_certificate'; + +$plugin->maturity = MATURITY_STABLE; +$plugin->release = "Master (Build: 2018040201)"; // User-friendly version number diff --git a/view.php b/view.php index 283d71c..2d44acb 100644 --- a/view.php +++ b/view.php @@ -18,15 +18,14 @@ /** * Handles viewing a certificate * - * @package mod - * @subpackage certificate + * @package mod_certificate * @copyright Mark Nelson * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once("../../config.php"); +require_once("$CFG->dirroot/mod/certificate/locallib.php"); require_once("$CFG->dirroot/mod/certificate/deprecatedlib.php"); -require_once("$CFG->dirroot/mod/certificate/lib.php"); require_once("$CFG->libdir/pdflib.php"); $id = required_param('id', PARAM_INT); // Course Module ID @@ -43,12 +42,18 @@ if (!$certificate = $DB->get_record('certificate', array('id'=> $cm->instance))) print_error('course module is incorrect'); } -require_login($course->id, false, $cm); +require_login($course, false, $cm); $context = context_module::instance($cm->id); require_capability('mod/certificate:view', $context); -// log update -add_to_log($course->id, 'certificate', 'view', "view.php?id=$cm->id", $certificate->id, $cm->id); +$event = \mod_certificate\event\course_module_viewed::create(array( + 'objectid' => $certificate->id, + 'context' => $context, +)); +$event->add_record_snapshot('course', $course); +$event->add_record_snapshot('certificate', $certificate); +$event->trigger(); + $completion=new completion_info($course); $completion->set_module_viewed($cm); @@ -59,9 +64,6 @@ $PAGE->set_cm($cm); $PAGE->set_title(format_string($certificate->name)); $PAGE->set_heading(format_string($course->fullname)); -// Set the context -$context = context_module::instance($cm->id); - if (($edit != -1) and $PAGE->user_allowed_editing()) { $USER->editing = $edit; } @@ -90,6 +92,7 @@ if (!$completion->is_course_complete($USER->id) && !has_capability('mod/certific die; } + // Create new certificate record, or return existing record $certrecord = certificate_get_issue($course, $USER, $certificate, $cm); @@ -101,8 +104,8 @@ require("$CFG->dirroot/mod/certificate/type/$certificate->certificatetype/certif if (empty($action)) { // Not displaying PDF echo $OUTPUT->header(); - /// find out current groups mode - groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/certificate/view.php?id=' . $cm->id); + $viewurl = new moodle_url('/mod/certificate/view.php', array('id' => $cm->id)); + groups_print_activity_menu($cm, $viewurl); $currentgroup = groups_get_activity_group($cm); $groupmode = groups_get_activity_groupmode($cm); @@ -129,32 +132,41 @@ if (empty($action)) { // Not displaying PDF } echo html_writer::tag('p', $str, array('style' => 'text-align:center')); $linkname = get_string('getcertificate', 'certificate'); - // Add to log, only if we are reissuing - add_to_log($course->id, 'certificate', 'view', "view.php?id=$cm->id", $certificate->id, $cm->id); $link = new moodle_url('/mod/certificate/view.php?id='.$cm->id.'&action=get'); $button = new single_button($link, $linkname); - $button->add_action(new popup_action('click', $link, 'view'.$cm->id, array('height' => 600, 'width' => 800))); + if ($certificate->delivery != 1) { + $button->add_action(new popup_action('click', $link, 'view' . $cm->id, array('height' => 600, 'width' => 800))); + } echo html_writer::tag('div', $OUTPUT->render($button), array('style' => 'text-align:center')); echo $OUTPUT->footer($course); exit; } else { // Output to pdf - // Remove full-stop at the end if it exists, to avoid "..pdf" being created and being filtered by clean_filename - $certname = rtrim($certificate->name, '.'); - $filename = clean_filename("$certname.pdf"); + + // No debugging here, sorry. + $CFG->debugdisplay = 0; + @ini_set('display_errors', '0'); + @ini_set('log_errors', '1'); + + $filename = certificate_get_certificate_filename($certificate, $cm, $course) . '.pdf'; + + // PDF contents are now in $file_contents as a string. + $filecontents = $pdf->Output('', 'S'); + if ($certificate->savecert == 1) { - // PDF contents are now in $file_contents as a string - $file_contents = $pdf->Output('', 'S'); - certificate_save_pdf($file_contents, $certrecord->id, $filename, $context->id); + certificate_save_pdf($filecontents, $certrecord->id, $filename, $context->id); } + if ($certificate->delivery == 0) { - $pdf->Output($filename, 'I'); // open in browser + // Open in browser. + send_file($filecontents, $filename, 0, 0, true, false, 'application/pdf'); } elseif ($certificate->delivery == 1) { - $pdf->Output($filename, 'D'); // force download when create + // Force download. + send_file($filecontents, $filename, 0, 0, true, true, 'application/pdf'); } elseif ($certificate->delivery == 2) { - certificate_email_student($course, $certificate, $certrecord, $context); - $pdf->Output($filename, 'I'); // open in browser - $pdf->Output('', 'S'); // send + certificate_email_student($course, $certificate, $certrecord, $context, $filecontents, $filename); + // Open in browser after sending email. + send_file($filecontents, $filename, 0, 0, true, false, 'application/pdf'); } }