public function execute()
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . '/mod/emarking/lib.php';
     require_once $CFG->dirroot . '/mod/emarking/locallib.php';
     require_once $CFG->dirroot . '/mod/emarking/print/locallib.php';
     $digitizedanswerfiles = emarking_get_digitized_answer_files(NULL, EMARKING_DIGITIZED_ANSWER_UPLOADED);
     if (count($digitizedanswerfiles) == 0) {
         mtrace('No digitized answers files to process');
         return;
     }
     $totalfiles = 0;
     // Setup de directorios temporales.
     $tempdir = emarking_get_temp_dir_path(random_string());
     emarking_initialize_directory($tempdir, true);
     foreach ($digitizedanswerfiles as $digitizedanswerfile) {
         if (!($zipfile = emarking_get_path_from_hash($tempdir, $digitizedanswerfile->hash))) {
             mtrace('Invalid file for processing ' . $digitizedanswerfile->id);
             continue;
         }
         if (!($emarking = $DB->get_record('emarking', array('id' => $digitizedanswerfile->emarking)))) {
             mtrace('Invalid emarking activity ' . $digitizedanswerfile->emarking);
             continue;
         }
         if (!($course = $DB->get_record('course', array('id' => $emarking->course)))) {
             mtrace('Invalid course in emarking activity ' . $emarking->course);
             continue;
         }
         if (!($cm = get_coursemodule_from_instance('emarking', $emarking->id))) {
             mtrace('Invalid course module for emarking activity ' . $emarking->id);
             continue;
         }
         $totalfiles++;
         $msg = "[{$totalfiles}] : {$course->fullname} ({$course->id}) : {$emarking->name} ({$emarking->id}) : {$digitizedanswerfile->filename} ({$digitizedanswerfile->id})";
         $digitizedanswerfile->status = EMARKING_DIGITIZED_ANSWER_BEING_PROCESSED;
         $DB->update_record('emarking_digitized_answers', $digitizedanswerfile);
         // Process documents and obtain results.
         list($result, $errors, $totaldocumentsprocessed, $totaldocumentsignored) = emarking_upload_answers($emarking, $zipfile, $course, $cm);
         if ($result) {
             $digitizedanswerfile->status = EMARKING_DIGITIZED_ANSWER_PROCESSED;
         } else {
             $digitizedanswerfile->status = EMARKING_DIGITIZED_ANSWER_ERROR_PROCESSING;
         }
         $digitizedanswerfile->totalpages = $totaldocumentsprocessed;
         $digitizedanswerfile->identifiedpages = $totaldocumentsprocessed - $totaldocumentsignored;
         $msg .= emarking_get_string_for_status_digitized($digitizedanswerfile->status) . ' processed:' . $totaldocumentsprocessed . ' ignored:' . $totaldocumentsignored;
         $DB->update_record('emarking_digitized_answers', $digitizedanswerfile);
         mtrace($msg);
     }
     mtrace("A total of {$totalfiles} were processed.");
 }
Esempio n. 2
0
         echo $OUTPUT->error_text(get_string('fileisnotzip', 'mod_emarking'));
         echo $OUTPUT->continue_button($urlemarking);
         echo $OUTPUT->box_end();
         echo $OUTPUT->footer();
         die;
     }
     // Parameters for execution
     $merge = isset($mform->get_data()->merge) ? false : true;
     // Inverted as question in form was inverted
     $nocache = rand(1, 999999);
     // File is ok, process
     // Setup de directorios temporales
     $tempdir = emarking_get_temp_dir_path($emarking->id);
     emarking_initialize_directory($tempdir, true);
     // Gets file hash
     $newfile = emarking_get_path_from_hash($tempdir, $file->get_pathnamehash(), '', true);
     // Display confirmation page before moving to process
     echo $OUTPUT->header();
     echo $OUTPUT->heading(get_string('confirmprocess', 'mod_emarking'));
     echo $OUTPUT->tabtree(emarking_tabs($context, $cm, $emarking), "uploadanswers");
     echo $OUTPUT->box_start('generalbox');
     // If the user confirms it goes to process.php
     $confirmurl = new moodle_url('/mod/emarking/print/processanswers.php', array('merge' => $merge, 'file' => $file->get_pathnamehash(), 'emarkingid' => $emarking->id));
     // Message changes if it will be merged
     $confirmessage = $merge ? 'confirmprocessfilemerge' : 'confirmprocessfile';
     // Show confirmation buttons
     echo $OUTPUT->confirm(get_string($confirmessage, 'mod_emarking', array('file' => $file->get_filename(), 'assignment' => $emarking->name)), $confirmurl, $urlemarking);
     echo $OUTPUT->box_end();
     echo $OUTPUT->footer();
     die;
 }
Esempio n. 3
0
 /**
  * Validates the answer key file
  * @param unknown $data
  * @return multitype:Ambigous <string, lang_string> |multitype:string Ambigous <string, lang_string>
  */
 private function get_answerkey_file_errors($data)
 {
     global $USER, $COURSE;
     $errors = array();
     // We get the draftid from the form.
     $draftid = file_get_submitted_draft_itemid('answerkeyfile');
     $usercontext = context_user::instance($USER->id);
     $fs = get_file_storage();
     $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftid);
     $tempdir = emarking_get_temp_dir_path($COURSE->id);
     emarking_initialize_directory($tempdir, true);
     $numpagesprevious = -1;
     $exampdfs = array();
     foreach ($files as $uploadedfile) {
         if ($uploadedfile->is_directory()) {
             continue;
         }
         if ($uploadedfile->get_mimetype() !== 'application/pdf') {
             $errors['exam_files'] = get_string('invalidfilenotpdf', 'mod_emarking') . '_' . $uploadedfile->get_mimetype() . '_' . $uploadedfile->get_filename();
             return $errors;
         }
         $filename = $uploadedfile->get_filename();
         $filename = emarking_clean_filename($filename);
         $newfilename = $tempdir . '/' . $filename;
         $pdffile = emarking_get_path_from_hash($tempdir, $uploadedfile->get_pathnamehash());
         // Executes pdftk burst to get all pages separated.
         $numpages = emarking_pdf_count_pages($newfilename, $tempdir, false);
         if (!is_numeric($numpages) || $numpages < 1) {
             $errors['exam_files'] = get_string('invalidpdfnopages', 'mod_emarking');
             return $errors;
         }
         if ($numpagesprevious >= 0 && $numpagesprevious != $numpages) {
             $errors['exam_files'] = get_string('invalidpdfnumpagesforms', 'mod_emarking');
             return $errors;
         }
         $exampdfs[] = array('pathname' => $pdffile, 'filename' => $filename);
     }
     if (count($exampdfs) == 0 && $data['exam'] == 0) {
         $errors['exam_files'] = get_string('filerequiredtosendnewprintorder', 'mod_emarking');
         return $errors;
     }
     return $errors;
 }
Esempio n. 4
0
/**
 * Saves a new instance of the emarking into the database
 *
 * Given an object containing all the necessary data,
 * (defined by the form in mod_form.php) this function
 * will create a new instance and return the id number
 * of the new instance.
 *
 * @param object $emarking
 *            An object from the form in mod_form.php
 * @param mod_emarking_mod_form $mform            
 * @return int The id of the newly inserted emarking record
 */
function emarking_add_instance(stdClass $data, mod_emarking_mod_form $mform = null)
{
    global $DB, $CFG, $COURSE, $USER;
    $data->timecreated = time();
    $id = $DB->insert_record('emarking', $data);
    $data->id = $id;
    emarking_grade_item_update($data);
    if ($data->type == EMARKING_TYPE_MARKER_TRAINING) {
        return $id;
    }
    foreach ($data as $k => $v) {
        $parts = explode('-', $k);
        if (count($parts) > 1 && $parts[0] === 'marker') {
            $markerid = intval($parts[1]);
            $marker = new stdClass();
            $marker->emarking = $id;
            $marker->marker = $markerid;
            $marker->qualitycontrol = 1;
            $DB->insert_record('emarking_markers', $marker);
        }
    }
    $context = context_course::instance($COURSE->id);
    $examid = 0;
    // If there's no previous exam to associate, and we are creating a new
    // e-marking, we need the PDF file
    if ($data->exam == 0) {
        // We get the draftid from the form
        $draftid = file_get_submitted_draft_itemid('exam_files');
        $usercontext = context_user::instance($USER->id);
        $fs = get_file_storage();
        $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftid);
        $tempdir = emarking_get_temp_dir_path($COURSE->id);
        emarking_initialize_directory($tempdir, true);
        $numpagesprevious = -1;
        $exampdfs = array();
        foreach ($files as $uploadedfile) {
            if ($uploadedfile->get_mimetype() !== 'application/pdf') {
                continue;
            }
            $filename = $uploadedfile->get_filename();
            $filename = emarking_clean_filename($filename);
            $newfilename = $tempdir . '/' . $filename;
            $pdffile = emarking_get_path_from_hash($tempdir, $uploadedfile->get_pathnamehash());
            // Executes pdftk burst to get all pages separated
            $numpages = emarking_pdf_count_pages($newfilename, $tempdir, false);
            $exampdfs[] = array('pathname' => $pdffile, 'filename' => $filename);
        }
    } else {
        $examid = $data->exam;
    }
    $studentsnumber = emarking_get_students_count_for_printing($COURSE->id);
    // A new exam object is created and its attributes filled from form data
    if ($examid == 0) {
        $exam = new stdClass();
        $exam->course = $COURSE->id;
        $exam->courseshortname = $COURSE->shortname;
        $exam->name = $mform->get_data()->name;
        $exam->examdate = $mform->get_data()->examdate;
        $exam->emarking = $id;
        $exam->headerqr = isset($mform->get_data()->headerqr) ? 1 : 0;
        $exam->printrandom = isset($mform->get_data()->printrandom) ? 1 : 0;
        $exam->printlist = isset($mform->get_data()->printlist) ? 1 : 0;
        $exam->extrasheets = $mform->get_data()->extrasheets;
        $exam->extraexams = $mform->get_data()->extraexams;
        $exam->usebackside = isset($mform->get_data()->printdoublesided) ? 1 : 0;
        if ($examid == 0) {
            $exam->timecreated = time();
        }
        $exam->timemodified = time();
        $exam->requestedby = $USER->id;
        $exam->totalstudents = $studentsnumber;
        // Get the enrolments as a comma separated values
        $enrollist = array();
        if (!empty($mform->get_data()->enrolments)) {
            $enrolments = $mform->get_data()->enrolments;
            foreach ($enrolments as $key => $enrolment) {
                if (!empty($enrolment)) {
                    $enrollist[] = $key;
                }
            }
        }
        $exam->enrolments = implode(",", $enrollist);
        $exam->printdate = 0;
        $exam->status = EMARKING_EXAM_UPLOADED;
        // Calculate total pages for exam
        $exam->totalpages = $numpages;
        $exam->id = $DB->insert_record('emarking_exams', $exam);
        foreach ($exampdfs as $exampdf) {
            // Save the submitted file to check if it's a PDF
            $filerecord = array('component' => 'mod_emarking', 'filearea' => 'exams', 'contextid' => $context->id, 'itemid' => $exam->id, 'filepath' => '/', 'filename' => $exampdf['filename']);
            $file = $fs->create_file_from_pathname($filerecord, $exampdf['pathname']);
        }
        // Update exam object to store the PDF's file id
        $exam->file = $file->get_id();
        if (!$DB->update_record('emarking_exams', $exam)) {
            $fs->delete_area_files($contextid, 'emarking', 'exams', $exam->id);
            print_error(get_string('errorsavingpdf', 'mod_emarking'));
        }
        // Send new print order notification
        emarking_send_newprintorder_notification($exam, $COURSE);
        // If it is a multi-course submission, insert several exams
        if (!empty($mform->get_data()->multicourse)) {
            $multicourse = $mform->get_data()->multicourse;
            foreach ($multicourse as $key => $mcourse) {
                if (!empty($key)) {
                    if ($thiscourse = $DB->get_record('course', array('shortname' => $key))) {
                        $studentsnumber = emarking_get_students_count_for_printing($thiscourse->id);
                        $newexam = $exam;
                        $newexam->id = null;
                        $newexam->totalstudents = $studentsnumber;
                        $newexam->course = $thiscourse->id;
                        $newexam->courseshortname = $thiscourse->shortname;
                        $newexam->emarking = 0;
                        $newexam->id = $DB->insert_record('emarking_exams', $newexam);
                        $thiscontext = context_course::instance($thiscourse->id);
                        // Create file records for all new exams
                        foreach ($exampdfs as $exampdf) {
                            // Save the submitted file to check if it's a PDF
                            $filerecord = array('component' => 'mod_emarking', 'filearea' => 'exams', 'contextid' => $thiscontext->id, 'itemid' => $newexam->id, 'filepath' => '/', 'filename' => $exampdf['filename']);
                            $file = $fs->create_file_from_pathname($filerecord, $exampdf['pathname']);
                        }
                        // Send new print order notification
                        emarking_send_newprintorder_notification($newexam, $thiscourse);
                    }
                }
            }
        }
    } else {
        $exam = $DB->get_record("emarking_exams", array("id" => $examid));
        $exam->emarking = $id;
        $exam->timemodified = time();
        $DB->update_record('emarking_exams', $exam);
    }
    $headerqr = isset($mform->get_data()->headerqr) ? 1 : 0;
    setcookie("emarking_headerqr", $headerqr, time() + 3600 * 24 * 365 * 10, '/');
    $defaultexam = new stdClass();
    $defaultexam->headerqr = $exam->headerqr;
    $defaultexam->printrandom = $exam->printrandom;
    $defaultexam->printlist = $exam->printlist;
    $defaultexam->extrasheets = $exam->extrasheets;
    $defaultexam->extraexams = $exam->extraexams;
    $defaultexam->usebackside = $exam->usebackside;
    $defaultexam->enrolments = $exam->enrolments;
    setcookie("emarking_exam_defaults", json_encode($defaultexam), time() + 3600 * 24 * 365 * 10, '/');
    return $id;
}
Esempio n. 5
0
/**
 * Creates a personalized exam file.
 *
 * @param unknown $examid            
 * @return NULL
 */
function emarking_download_exam($examid, $multiplepdfs = false, $groupid = null, progress_bar $pbar = null, $sendprintorder = false, $idprinter = null, $printanswersheet = false, $debugprinting = false)
{
    global $DB, $CFG, $USER, $OUTPUT;
    require_once $CFG->dirroot . '/mod/emarking/lib/openbub/ans_pdf_open.php';
    // Validate emarking exam object
    if (!($downloadexam = $DB->get_record('emarking_exams', array('id' => $examid)))) {
        throw new Exception(get_string("invalidexamid", "mod_emarking"));
    }
    // Contexto del curso para verificar permisos
    $context = context_course::instance($downloadexam->course);
    if (!has_capability('mod/emarking:downloadexam', $context)) {
        throw new Exception(get_string("invalidaccess", "mod_emarking"));
    }
    // Verify that remote printing is enable, otherwise disable a printing order
    if ($sendprintorder && (!$CFG->emarking_enableprinting || $idprinter == null)) {
        throw new Exception('Printing is not enabled or printername was absent ' . $idprinter);
    }
    // Validate course
    if (!($course = $DB->get_record('course', array('id' => $downloadexam->course)))) {
        throw new Exception(get_string("invalidcourse", "mod_emarking"));
    }
    // Validate course category
    if (!($coursecat = $DB->get_record('course_categories', array('id' => $course->category)))) {
        throw new Exception(get_string("invalidcategoryid", "mod_emarking"));
    }
    // We tell the user we are setting up the printing
    if ($pbar) {
        $pbar->update(0, 1, get_string('settingupprinting', 'mod_emarking'));
    }
    // Default value for enrols that will be included
    if ($CFG->emarking_enrolincludes && strlen($CFG->emarking_enrolincludes) > 1) {
        $enrolincludes = $CFG->emarking_enrolincludes;
    }
    // If the exam sets enrolments, we use those
    if (isset($downloadexam->enrolments) && strlen($downloadexam->enrolments) > 1) {
        $enrolincludes = $downloadexam->enrolments;
    }
    // Convert enrolments to array
    $enrolincludes = explode(",", $enrolincludes);
    // Produce all PDFs first separatedly
    $filedir = $CFG->dataroot . "/temp/emarking/{$context->id}";
    $fileimg = $filedir . "/qr";
    $userimgdir = $filedir . "/u";
    $pdfdir = $filedir . "/pdf";
    emarking_initialize_directory($filedir, true);
    emarking_initialize_directory($fileimg, true);
    emarking_initialize_directory($userimgdir, true);
    emarking_initialize_directory($pdfdir, true);
    // Get all the files uploaded as forms for this exam
    $fs = get_file_storage();
    $files = $fs->get_area_files($context->id, 'mod_emarking', 'exams', $examid);
    // We filter only the PDFs
    $pdffileshash = array();
    foreach ($files as $filepdf) {
        if ($filepdf->get_mimetype() === 'application/pdf') {
            $pdffileshash[] = array('hash' => $filepdf->get_pathnamehash(), 'filename' => $filepdf->get_filename(), 'path' => emarking_get_path_from_hash($filedir, $filepdf->get_pathnamehash()));
        }
    }
    // Verify that at least we have a PDF
    if (count($pdffileshash) < 1) {
        throw new Exception(get_string("examhasnopdf", "mod_emarking"));
    }
    $students = emarking_get_students_for_printing($downloadexam->course);
    $studentinfo = array();
    $currenttemplate = 0;
    // Fill studentnames with student info (name, idnumber, id and picture)
    foreach ($students as $student) {
        $studentenrolments = explode(",", $student->enrol);
        // Verifies that the student is enrolled through a valid enrolment and that we haven't added her yet
        if (count(array_intersect($studentenrolments, $enrolincludes)) == 0 || isset($studentinfo[$student->id])) {
            continue;
        }
        // We create a student info object
        $studentobj = new stdClass();
        $studentobj->name = substr("{$student->lastname}, {$student->firstname}", 0, 65);
        $studentobj->idnumber = $student->idnumber;
        $studentobj->id = $student->id;
        $studentobj->picture = emarking_get_student_picture($student, $userimgdir);
        // Store student info in hash so every student is stored once
        $studentinfo[$student->id] = $studentobj;
    }
    // We validate the number of students as we are filtering by enrolment
    // type after getting the data
    $numberstudents = count($studentinfo);
    if ($numberstudents == 0) {
        throw new Exception('No students to print/create the exam');
    }
    // Add the extra students to the list
    for ($i = $numberstudents; $i < $numberstudents + $downloadexam->extraexams; $i++) {
        $studentobj = new stdClass();
        $studentobj->name = '..............................................................................';
        $studentobj->idnumber = 0;
        $studentobj->id = 0;
        $studentobj->picture = $CFG->dirroot . "/pix/u/f1.png";
        $studentinfo[] = $studentobj;
    }
    // Check if there is a logo file
    $logofilepath = emarking_get_logo_file($filedir);
    // If asked to do so we create a PDF witht the students list
    if ($downloadexam->printlist == 1) {
        $pdf = new FPDI();
        $pdf->SetPrintHeader(false);
        $pdf->SetPrintFooter(false);
        emarking_draw_student_list($pdf, $logofilepath, $downloadexam, $course, $studentinfo);
        $studentlistpdffile = $pdfdir . "/000-studentslist.pdf";
        $pdf->Output($studentlistpdffile, "F");
        // se genera el nuevo pdf
        $pdf = null;
    }
    // Here we produce a PDF file for each student
    $currentstudent = 0;
    foreach ($studentinfo as $stinfo) {
        // If we have a progress bar, we notify the new PDF being created
        if ($pbar) {
            $pbar->update($currentstudent + 1, count($studentinfo), $stinfo->name);
        }
        // We create the PDF file
        $pdf = new FPDI();
        $pdf->SetPrintHeader(false);
        $pdf->SetPrintFooter(false);
        // We use the next form available from the list of PDF forms sent
        if ($currenttemplate >= count($pdffileshash) - 1) {
            $currenttemplate = 0;
        } else {
            $currenttemplate++;
        }
        // Load the PDF from the filesystem as template
        $path = $pdffileshash[$currenttemplate]['path'];
        $originalpdfpages = $pdf->setSourceFile($path);
        $pdf->SetAutoPageBreak(false);
        // Add all pages in the template, adding the header if it corresponds
        for ($pagenumber = 1; $pagenumber <= $originalpdfpages + $downloadexam->extrasheets; $pagenumber++) {
            // Adding a page
            $pdf->AddPage();
            // If the page is not an extra page, we import the page from the template
            if ($pagenumber <= $originalpdfpages) {
                $template = $pdf->importPage($pagenumber);
                $pdf->useTemplate($template, 0, 0, 0, 0, true);
            }
            // If we have a personalized header, we add it
            if ($downloadexam->headerqr) {
                emarking_draw_header($pdf, $stinfo, $downloadexam->name, $pagenumber, $fileimg, $logofilepath, $course, $originalpdfpages + $downloadexam->extrasheets);
            }
        }
        // The filename will be the student id - course id - page number
        $qrstringtmp = $stinfo->id > 0 ? "{$stinfo->id}-{$course->id}-{$pagenumber}" : "NN{$currentstudent}+1-{$course->id}-{$pagenumber}";
        // Create the PDF file for the student
        $pdffile = $pdfdir . "/" . $qrstringtmp . ".pdf";
        $pdf->Output($pdffile, "F");
        // Store the exam file for printing later
        $stinfo->examfile = $pdffile;
        $stinfo->number = $currentstudent + 1;
        $stinfo->pdffilename = $qrstringtmp;
        $currentstudent++;
    }
    $sqlprinter = "SELECT id, name, command\n\t\t\tFROM {emarking_printers}\n\t\t\tWHERE id = ?";
    $printerinfo = $DB->get_record_sql($sqlprinter, array($idprinter));
    // If we have to print directly
    $debugprintingmsg = '';
    if ($sendprintorder) {
        // Check if we have to print the students list
        if ($downloadexam->printlist == 1) {
            $printresult = emarking_print_file($printerinfo->name, $printerinfo->command, $studentlistpdffile, $debugprinting);
            if (!$printresult) {
                $debugprintingmsg .= 'Problems printing ' . $studentlistpdffile . '<hr>';
            } else {
                $debugprintingmsg .= $printresult . '<hr>';
            }
        }
        // Print each student
        $currentstudent = 0;
        foreach ($studentinfo as $stinfo) {
            $currentstudent++;
            if ($pbar != null) {
                $pbar->update($currentstudent, count($studentinfo), get_string('printing', 'mod_emarking') . ' ' . $stinfo->name);
            }
            if (!isset($stinfo->examfile) || !file_exists($stinfo->examfile)) {
                continue;
            }
            $printresult = emarking_print_file($printerinfo->name, $printerinfo->command, $stinfo->examfile, $debugprinting);
            if (!$printresult) {
                $debugprintingmsg .= 'Problems printing ' . $stinfo->examfile . '<hr>';
            } else {
                $debugprintingmsg .= $printresult . '<hr>';
            }
        }
        if ($CFG->debug || $debugprinting) {
            echo $debugprintingmsg;
        }
        // Notify everyone that the exam was printed
        emarking_send_examprinted_notification($downloadexam, $course);
        $downloadexam->status = EMARKING_EXAM_SENT_TO_PRINT;
        $downloadexam->printdate = time();
        $DB->update_record('emarking_exams', $downloadexam);
        return true;
    }
    $examfilename = emarking_clean_filename($course->shortname, true) . "_" . emarking_clean_filename($downloadexam->name, true);
    $zipdebugmsg = '';
    if ($multiplepdfs) {
        $zip = new ZipArchive();
        $zipfilename = $filedir . "/" . $examfilename . ".zip";
        if ($zip->open($zipfilename, ZipArchive::CREATE) !== true) {
            throw new Exception('Could not create zip file');
        }
        // Check if we have to print the students list
        if ($downloadexam->printlist == 1) {
            $zip->addFile($studentlistpdffile);
        }
        // Add every student PDF to zip file
        $currentstudent = 0;
        foreach ($studentinfo as $stinfo) {
            $currentstudent++;
            if ($pbar != null) {
                $pbar->update($currentstudent, count($studentinfo), get_string('printing', 'mod_emarking') . ' ' . $stinfo->name);
            }
            if (!isset($stinfo->examfile) || !file_exists($stinfo->examfile)) {
                continue;
            }
            if (!$zip->addFile($stinfo->examfile, $stinfo->pdffilename . '.pdf')) {
                $zipdebugmsg .= "Problems adding {$stinfo->examfile} to ZIP file using name {$stinfo->pdffilename} <hr>";
            }
        }
        $zip->close();
        if ($CFG->debug || $debugprinting) {
            echo $zipdebugmsg;
        }
        // Notify everyone that the exam was downloaded
        emarking_send_examdownloaded_notification($downloadexam, $course);
        $downloadexam->status = EMARKING_EXAM_SENT_TO_PRINT;
        $downloadexam->printdate = time();
        $DB->update_record('emarking_exams', $downloadexam);
        // Read zip file from disk and send to the browser
        $file_name = basename($zipfilename);
        header("Content-Type: application/zip");
        header("Content-Disposition: attachment; filename=" . $examfilename . ".zip");
        header("Content-Length: " . filesize($zipfilename));
        readfile($zipfilename);
        exit;
    }
    // We create the final big PDF file
    $pdf = new FPDI();
    $pdf->SetPrintHeader(false);
    $pdf->SetPrintFooter(false);
    // We import the students list if required
    if ($downloadexam->printlist) {
        emarking_import_pdf_into_pdf($pdf, $studentlistpdffile);
    }
    // Add every student PDF to zip file
    $currentstudent = 0;
    foreach ($studentinfo as $stinfo) {
        $currentstudent++;
        if (!isset($stinfo->examfile) || !file_exists($stinfo->examfile)) {
            continue;
        }
        emarking_import_pdf_into_pdf($pdf, $stinfo->examfile);
    }
    // Notify everyone that the exam was downloaded
    emarking_send_examdownloaded_notification($downloadexam, $course);
    $downloadexam->status = EMARKING_EXAM_SENT_TO_PRINT;
    $downloadexam->printdate = time();
    $DB->update_record('emarking_exams', $downloadexam);
    $pdf->Output($examfilename . '.pdf', 'D');
}
Esempio n. 6
0
/**
 * Crea un archivo PDF a partir de un quiz, agregando una hoja de respuestas de opción múltiple
 * 
 * @param unknown $cm
 * @param string $debug
 * @param string $context
 * @param string $course
 * @param string $logofilepath
 * @param boolean $answersheetsonly
 * @return void|NULL
 */
function emarking_create_quiz_pdf($cm, $debug = false, $context = null, $course = null, $answersheetsonly = false, $pbar = false)
{
    global $DB, $CFG, $OUTPUT;
    // Inclusión de librerías
    require_once $CFG->dirroot . '/mod/assign/feedback/editpdf/fpdi/fpdi2tcpdf_bridge.php';
    require_once $CFG->dirroot . '/mod/assign/feedback/editpdf/fpdi/fpdi.php';
    require_once $CFG->libdir . '/pdflib.php';
    require_once $CFG->dirroot . '/mod/quiz/locallib.php';
    require_once $CFG->dirroot . '/mod/emarking/print/locallib.php';
    $filedir = $CFG->dataroot . "/temp/emarking/{$context->id}";
    emarking_initialize_directory($filedir, true);
    $fileimg = $CFG->dataroot . "/temp/emarking/{$context->id}/qr";
    emarking_initialize_directory($fileimg, true);
    $userimgdir = $CFG->dataroot . "/temp/emarking/{$context->id}/u";
    emarking_initialize_directory($userimgdir, true);
    $logofile = emarking_get_logo_file();
    $logofilepath = $logofile ? emarking_get_path_from_hash($filedir, $logofile->get_pathnamehash()) : null;
    $fullhtml = array();
    $numanswers = array();
    $attemptids = array();
    $images = array();
    $imageshtml = array();
    $users = emarking_get_enroled_students($course->id);
    if ($pbar) {
        echo $OUTPUT->heading(get_string('loadingquestions', 'mod_emarking'), 3);
        $progressbar = new progress_bar();
        $progressbar->create();
        $progressbar->update(0, count($users), get_string('processing', 'mod_emarking'));
    }
    $current = 0;
    foreach ($users as $user) {
        $current++;
        if ($pbar) {
            $progressbar->update($current, count($users), "{$user->firstname}, {$user->lastname}");
        }
        // Get the quiz object
        $quizobj = quiz::create($cm->instance, $user->id);
        // Create the new attempt and initialize the question sessions
        $attemptnumber = 1;
        $lastattempt = null;
        $timenow = time();
        // Update time now, in case the server is running really slowly.
        $attempts = quiz_get_user_attempts($quizobj->get_quizid(), $user->id, 'all');
        $numattempts = count($attempts);
        foreach ($attempts as $attempt) {
            $attemptobj = quiz_attempt::create($attempt->id);
            $slots = $attemptobj->get_slots();
            foreach ($slots as $slot) {
                $qattempt = $attemptobj->get_question_attempt($slot);
                $question = $qattempt->get_question();
                if ($question->get_type_name() === 'multianswer') {
                    $q = $question->subquestions[1];
                    $numanswers[$user->id][] = count($q->answers);
                } else {
                    if ($question->get_type_name() === 'multichoice') {
                        $numanswers[$user->id][] = count($question->answers);
                    }
                }
                $attemptids[$user->id] = $attempt->id;
                $qhtml = $attemptobj->render_question($slot, false);
                $qhtml = emarking_clean_question_html($qhtml);
                $currentimages = emarking_extract_images_url($qhtml);
                $idx = 0;
                foreach ($currentimages[1] as $imageurl) {
                    if (!array_search($imageurl, $images)) {
                        $images[] = $imageurl;
                        $imageshtml[] = $currentimages[0][$idx];
                    }
                    $idx++;
                }
                $fullhtml[$user->id][] = $qhtml;
            }
            // One attempt per user
            break;
        }
    }
    $save_to = $CFG->tempdir . '/emarking/printquiz/' . $cm->id . '/';
    emarking_initialize_directory($save_to, true);
    // Bajar las imágenes del HTML a dibujar
    $search = array();
    $replace = array();
    $replaceweb = array();
    $imagesize = array();
    $idx = 0;
    if ($pbar) {
        $progressbar->update_full(100, get_string('finished', 'mod_emarking'));
        echo $OUTPUT->heading(get_string('downloadingimages', 'mod_emarking'), 3);
        $progressbar = new progress_bar();
        $progressbar->create();
        $progressbar->update(0, count($images), get_string('processing', 'mod_emarking'));
    }
    foreach ($images as $image) {
        if ($pbar) {
            $imagefilename = explode("/", $image);
            $progressbar->update($idx + 1, count($images), $imagefilename[count($imagefilename) - 1]);
        }
        // Si solamente incluiremos hojas de respuesta terminamos el ciclo
        if ($answersheetsonly) {
            break;
        }
        if (!(list($filename, $imageinfo) = emarking_get_file_from_url($image, $save_to))) {
            echo "Problem downloading file {$image} <hr>";
        } else {
            // Buscamos el src de la imagen
            $search[] = 'src="' . $image . '"';
            $replacehtml = ' src="' . $filename . '"';
            $replacehtmlxweb = ' src="' . $image . '"';
            // Si el html de la misma contiene ancho o alto, se deja tal cual
            $imghtml = $imageshtml[$idx];
            if (substr_count($imghtml, "width") + substr_count($imghtml, "height") == 0) {
                $width = $imageinfo[0];
                $height = $imageinfo[1];
                $ratio = floatval(10) / floatval($height);
                $height = 10;
                $width = (int) ($ratio * floatval($width));
                $sizehtml = 'width="' . $width . '" height="' . $height . '"';
                $replacehtml = $sizehtml . ' ' . $replacehtml;
                $replacehtmlxweb = $sizehtml . ' ' . $replacehtmlxweb;
            }
            $replace[] = $replacehtml;
            $replaceweb[] = $replacehtmlxweb;
            $imagesize[] = $imageinfo;
        }
        $idx++;
    }
    if ($debug) {
        foreach ($fullhtml as $uid => $questions) {
            $index = 0;
            foreach ($questions as $question) {
                echo str_replace($search, $replaceweb, $fullhtml[$uid][$index]);
                $index++;
            }
        }
        return;
    }
    // Now we create the pdf file with the modified html
    $doc = new FPDI();
    $doc->setPrintHeader(false);
    $doc->setPrintFooter(false);
    $doc->SetFont('times', '', 12);
    // set margins
    $doc->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
    $doc->SetHeaderMargin(250);
    $doc->SetFooterMargin(PDF_MARGIN_FOOTER);
    if ($pbar) {
        $progressbar->update_full(100, get_string('finished', 'mod_emarking'));
        echo $OUTPUT->heading(get_string('creatingpdffile', 'mod_emarking'), 3);
        $progressbar = new progress_bar();
        $progressbar->create();
    }
    $current = 0;
    foreach ($fullhtml as $uid => $questions) {
        $current++;
        $stinfo = $DB->get_record('user', array('id' => $uid));
        $stinfo->name = $stinfo->firstname . ' ' . $stinfo->lastname;
        $stinfo->picture = emarking_get_student_picture($stinfo, $userimgdir);
        $stinfo->idnumber = $uid . '-' . $attemptids[$uid];
        if ($pbar) {
            $progressbar->update($current, count($fullhtml), $stinfo->name);
        }
        $groups = groups_get_user_groups($course->id, $uid);
        if ($groups && isset($groups[0][0]) && ($group = $DB->get_record('groups', array('id' => $groups[0][0])))) {
            $stinfo->group = $group->name;
        } else {
            $stinfo->group = '';
        }
        emarking_add_answer_sheet($doc, $filedir, $stinfo, $logofilepath, null, $fileimg, $course, $quizobj->get_quiz_name(), $numanswers[$uid], $attemptids[$uid]);
        // Una vez agregada la página de respuestas, si es todo lo que hay que hacer saltar al siguiente
        if ($answersheetsonly) {
            continue;
        }
        $doc->AddPage();
        emarking_draw_header($doc, $stinfo, $quizobj->get_quiz_name(), 2, $fileimg, $logofilepath, $course, null, false, 0);
        $doc->SetFont('times', '', 12);
        $doc->SetAutoPageBreak(true);
        $doc->SetXY(PDF_MARGIN_LEFT, 40);
        $index = 0;
        foreach ($questions as $question) {
            $prevy = $doc->getY();
            $fullhtml[$uid][$index] = str_replace($search, $replace, $fullhtml[$uid][$index]);
            $doc->writeHTML($fullhtml[$uid][$index]);
            $y = $doc->getY();
            $fmargin = $doc->getFooterMargin();
            $height = $doc->getPageHeight();
            $spaceleft = $height - $fmargin - $y;
            $questionsize = $y - $prevy;
            if ($spaceleft < 70) {
                $doc->AddPage();
            }
            $index++;
        }
    }
    if ($pbar) {
        $progressbar->update_full(100, get_string('finished', 'mod_emarking'));
    }
    $qid = $quizobj->get_quizid();
    $pdfquizfilename = 'quiz-' . $qid . '-' . random_string() . '.pdf';
    $fs = get_file_storage();
    $filerecord = array('component' => 'mod_emarking', 'filearea' => 'pdfquiz', 'contextid' => $context->id, 'itemid' => $quizobj->get_quizid(), 'filepath' => '/', 'filename' => $pdfquizfilename);
    $doc->Output($filedir . '/' . $pdfquizfilename, 'F');
    $file = $fs->create_file_from_pathname($filerecord, $filedir . '/' . $pdfquizfilename);
    $downloadurl = moodle_url::make_file_url("{$CFG->wwwroot}/pluginfile.php", "/{$context->id}/mod_emarking/pdfquiz/{$qid}/{$pdfquizfilename}", null, true);
    return $downloadurl;
}
Esempio n. 7
0
/**
 * Verifies if there's a logo for the personalized header, and if there is it copies it to the
 * module
 */
function emarking_get_logo_file($filedir)
{
    $fs = get_file_storage();
    $syscontext = context_system::instance();
    if ($files = $fs->get_area_files($syscontext->id, 'mod_emarking', 'logo', 1, "filename", false)) {
        foreach ($files as $file) {
            $filename = $file->get_filename();
            if ($filename !== '.') {
                $existingfile = $fs->get_file($syscontext->id, 'mod_emarking', 'logo', 1, '/', $file->get_filename());
                if ($existingfile) {
                    return emarking_get_path_from_hash($filedir, $existingfile->get_pathnamehash());
                }
            }
        }
    }
    return false;
}
Esempio n. 8
0
/**
 * Validates if the draft files uploaded by a user are valid PDF exams
 * 
 * @return array list of valid PDF exam files
 */
function emarking_validate_exam_files_from_draft()
{
    global $USER, $COURSE;
    // We get the draftid from the form.
    $draftid = file_get_submitted_draft_itemid('exam_files');
    $usercontext = context_user::instance($USER->id);
    $fs = get_file_storage();
    $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftid);
    $tempdir = emarking_get_temp_dir_path($COURSE->id);
    emarking_initialize_directory($tempdir, true);
    $numpagesprevious = -1;
    $exampdfs = array();
    foreach ($files as $uploadedfile) {
        if ($uploadedfile->is_directory() || $uploadedfile->get_mimetype() !== 'application/pdf') {
            continue;
        }
        $filename = $uploadedfile->get_filename();
        $filename = emarking_clean_filename($filename);
        $newfilename = $tempdir . '/' . $filename;
        $pdffile = emarking_get_path_from_hash($tempdir, $uploadedfile->get_pathnamehash());
        // Executes pdftk burst to get all pages separated.
        $numpages = emarking_pdf_count_pages($newfilename, $tempdir, false);
        $exampdfs[] = array('pathname' => $pdffile, 'filename' => $filename, 'numpages' => $numpages);
    }
    return $exampdfs;
}
Esempio n. 9
0
 function validation($data, $files)
 {
     global $CFG, $COURSE, $USER, $DB;
     require_once $CFG->dirroot . "/mod/emarking/print/locallib.php";
     if ($data["type"] < 0 || $data["type"] > 5) {
         return array("type" => get_string("markingtypemandatory", "mod_emarking"));
     }
     // Calculates context for validating permissions
     // If we have the module available, we use it, otherwise we fallback to course
     $ctx = context_course::instance($COURSE->id);
     if ($this->current && $this->current->coursemodule) {
         $cm = get_coursemodule_from_id('emarking', $this->current->module, $COURSE->id);
         if ($cm) {
             $ctx = context_module::instance($cm->id);
         }
     }
     $errors = array();
     // Verify that we have enough markers
     if ($data['type'] == EMARKING_TYPE_MARKER_TRAINING) {
         // Get all users with permission to grade in emarking
         $markers = get_enrolled_users($ctx, 'mod/emarking:grade');
         $totalmarkers = 0;
         foreach ($markers as $marker) {
             if (has_capability('mod/emarking:supervisegrading', $ctx, $marker)) {
                 continue;
             }
             $totalmarkers++;
         }
         if ($totalmarkers < 2) {
             $errors['type'] = get_string('notenoughmarkersfortraining', 'mod_emarking');
             return $errors;
         }
         return $errors;
     }
     // Get the exam if we are updating an emarking activity
     $exam = null;
     if (isset($data['exam']) && $data['exam'] > 0) {
         if (!($exam = $DB->get_record("emarking_exams", array("id" => $data["exam"])))) {
             $errors["exam"] = "Invalid data from form";
         }
     }
     // If there is no associated exam yet
     if (!$exam) {
         // The exam date comes from the date selector
         $examdate = new DateTime();
         $examdate->setTimestamp(usertime($data['examdate']));
         // Day of week from 0 Sunday to 6 Saturday
         $examw = date("w", $examdate->getTimestamp());
         // Hour of the day un 00 to 23 format
         $examh = date("H", $examdate->getTimestamp());
         // If minimum days for printing is enabled
         if (isset($CFG->emarking_minimumdaysbeforeprinting) && $CFG->emarking_minimumdaysbeforeprinting > 0) {
             // Sundays are forbidden, saturdays from 6am to 4pm TODO: Move this settings to eMarking settings
             if ($examw == 0 || $examw == 6 && ($examh < 6 || $examh > 16)) {
                 $errors['examdate'] = get_string('examdateinvaliddayofweek', 'mod_emarking');
             }
             // User date. Important because the user sees a date selector based on her timezone settings, not the server's
             $date = usertime(time());
             // Today is the date according to the user's timezone
             $today = new DateTime();
             $today->setTimestamp($date);
             // We have a minimum difference otherwise we wouldn't be in this part of the code
             $mindiff = intval($CFG->emarking_minimumdaysbeforeprinting);
             // If today is saturday or sunday, demand for a bigger difference
             $todayw = date("w", $today->getTimestamp());
             $todayw = $todayw ? $todayw : 7;
             if ($todayw > 5) {
                 $mindiff += $todayw - 5;
             }
             // DateInterval calculated with diff
             $diff = $today->diff($examdate, false);
             // The difference using the invert from DateInterval so we know it is in the past
             $realdiff = $diff->days * ($diff->invert ? -1 : 1);
             // If the difference is not enough, show an error
             if ($realdiff < $mindiff) {
                 $a = new stdClass();
                 $a->mindays = $mindiff;
                 $errors['examdate'] = get_string('examdateinvalid', 'mod_emarking', $a);
             }
         }
     }
     // If there's no previous exam to associate, and we are creating a new
     // e-marking, we need the PDF file
     if ($data["exam"] == 0 && !$this->_instance) {
         // We get the draftid from the form
         $draftid = file_get_submitted_draft_itemid('exam_files');
         $usercontext = context_user::instance($USER->id);
         $fs = get_file_storage();
         $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftid);
         $tempdir = emarking_get_temp_dir_path($COURSE->id);
         emarking_initialize_directory($tempdir, true);
         $numpagesprevious = -1;
         $exampdfs = array();
         foreach ($files as $uploadedfile) {
             if ($uploadedfile->get_mimetype() !== 'application/pdf') {
                 continue;
             }
             $filename = $uploadedfile->get_filename();
             $filename = emarking_clean_filename($filename);
             $newfilename = $tempdir . '/' . $filename;
             $pdffile = emarking_get_path_from_hash($tempdir, $uploadedfile->get_pathnamehash());
             // Executes pdftk burst to get all pages separated
             $numpages = emarking_pdf_count_pages($newfilename, $tempdir, false);
             if (!is_numeric($numpages) || $numpages < 1) {
                 $errors["exam_files"] = get_string('invalidpdfnopages', 'mod_emarking');
                 return $errors;
             }
             if ($numpagesprevious >= 0 && $numpagesprevious != $numpages) {
                 $errors["exam_files"] = get_string('invalidpdfnumpagesforms', 'mod_emarking');
                 return $errors;
             }
             $exampdfs[] = array('pathname' => $pdffile, 'filename' => $filename);
         }
         if (count($exampdfs) == 0) {
             $errors["exam_files"] = get_string('invalidpdfnopages', 'mod_emarking');
             return $errors;
         }
     }
     // Validate the adjusted slope
     $adjustslope = isset($data['adjustslope']) ? $data['adjustslope'] : false;
     $adjustslopescore = isset($data['adjustslopescore']) ? $data['adjustslopescore'] : 0;
     $adjustslopegrade = isset($data['adjustslopegrade']) ? $data['adjustslopegrade'] : 0;
     $grademin = $data['grademin'];
     $grademax = $data['grade'];
     $regradesopendate = $data['regradesopendate'];
     $regradesclosedate = $data['regradesclosedate'];
     // Make sure the minimum score is not greater than the maximum score
     if ($grademin >= $grademax) {
         $errors['grademin'] = get_string('gradescheck', 'mod_emarking');
         $errors['grade'] = get_string('gradescheck', 'mod_emarking');
     }
     // If we are adjusting the slope
     if ($adjustslope) {
         // Make sure the grade is greater than the minimum grade
         if ($adjustslopegrade <= $grademin) {
             $errors['adjustslopegrade'] = get_string('adjustslopegrademustbegreaterthanmin', 'mod_emarking');
         }
         // Make sure the grade is lower than the maximum grade
         if ($adjustslopegrade > $grademax) {
             $errors['adjustslopegrade'] = get_string('adjustslopegrademustbelowerthanmax', 'mod_emarking');
         }
         // And that the score for adjusting is greater than 0
         if ($adjustslopescore <= 0) {
             $errors['adjustslopescore'] = get_string('adjustslopescoregreaterthanzero', 'mod_emarking');
         }
     }
     // Validate regrade dates
     if ($regradesopendate > $regradesclosedate) {
         $errors['regradesopendate'] = get_string('verifyregradedate', 'mod_emarking');
         $errors['regradesclosedate'] = get_string('verifyregradedate', 'mod_emarking');
     }
     // Validate custom marks
     $custommarks = isset($data['custommarks']) ? $data['custommarks'] : '';
     $custommarks = str_replace('\\r\\n', '\\n', $custommarks);
     if (strlen($custommarks) > 0) {
         $parts = explode("\n", $custommarks);
         $linenumber = 0;
         foreach ($parts as $line) {
             $linenumber++;
             if (strlen(trim($line)) == 0) {
                 continue;
             }
             $subparts = explode("#", $line);
             if (count($subparts) != 2) {
                 if (!isset($errors['custommarks'])) {
                     $errors['custommarks'] = get_string('invalidcustommarks', 'mod_emarking');
                 }
                 $errors['custommarks'] .= "{$linenumber} ";
             }
         }
     }
     $qualitycontrol = isset($data['enablequalitycontrol']) ? $data['enablequalitycontrol'] : false;
     if ($data['type'] == EMARKING_TYPE_NORMAL && $qualitycontrol) {
         // Get all users with permission to grade in emarking
         // Get all users with permission to grade in emarking
         $markers = get_enrolled_users($ctx, 'mod/emarking:grade');
         $totalmarkers = 0;
         foreach ($markers as $marker) {
             if (isset($data['marker-' . $marker->id])) {
                 $totalmarkers++;
             }
         }
         if ($totalmarkers == 0) {
             $errors['markers'] = get_string('notenoughmarkersforqualitycontrol', 'mod_emarking');
         }
     }
     if ($data["exam"] > 0 && $this->_instance) {
         $previousexam = $DB->get_record("emarking_exams", array("emarking" => $this->_instance));
         if ($previousexam && $previousexam->id != $data["exam"]) {
             $errors["exam"] = "An exam is already assigned for this emarking activity";
         }
     }
     return $errors;
 }
Esempio n. 10
0
$PAGE->set_cm($cm);
$PAGE->set_title(get_string('emarking', 'mod_emarking'));
$PAGE->set_heading($course->fullname);
$PAGE->navbar->add(get_string('uploadanswers', 'mod_emarking'));
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('uploadinganswersheets', 'mod_emarking'));
// Create progress bar
$pbar = new progress_bar('extractqr', 500, true);
$pbar->create();
// Count documents ignored and processed
$totaldocumentsprocessed = 0;
$totaldocumentsignored = 0;
// Setup de directorios temporales
$tempdir = emarking_get_temp_dir_path($emarking->id);
emarking_initialize_directory($tempdir, true);
$zipfile = emarking_get_path_from_hash($tempdir, $fileid);
// Process documents and obtain results
list($result, $errors, $totaldocumentsprocessed, $totaldocumentsignored) = emarking_upload_answers($emarking, $zipfile, $course, $cm, $pbar);
$pbar->update_full(100, get_string('qrdecodingfinished', 'mod_emarking'));
$percentage = 0;
if ($totaldocumentsprocessed > 0) {
    $percentage = round(($totaldocumentsprocessed - $totaldocumentsignored) / $totaldocumentsprocessed * 100, 2);
}
$table = new html_table();
$table->attributes['style'] = "width: 500px; margin-left:auto; margin-right:auto;";
$table->head = array(get_string('results', 'mod_emarking'), '&nbsp;');
$table->data[] = array(get_string('identifieddocuments', 'mod_emarking'), $totaldocumentsprocessed . " ({$percentage}%)");
$table->data[] = array(get_string('ignoreddocuments', 'mod_emarking'), $totaldocumentsignored);
if (!$result) {
    $table->data[] = array(get_string('errors', 'mod_emarking'), $errors);
}
Esempio n. 11
0
 $draftid = file_get_submitted_draft_itemid('exam_files');
 $usercontext = context_user::instance($USER->id);
 $fs = get_file_storage();
 $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftid);
 $tempdir = emarking_get_temp_dir_path($course->id);
 emarking_initialize_directory($tempdir, true);
 $numpagesprevious = -1;
 $exampdfs = array();
 foreach ($files as $uploadedfile) {
     if ($uploadedfile->get_mimetype() !== 'application/pdf') {
         continue;
     }
     $filename = $uploadedfile->get_filename();
     $filename = emarking_clean_filename($filename);
     $newfilename = $tempdir . '/' . $filename;
     $pdffile = emarking_get_path_from_hash($tempdir, $uploadedfile->get_pathnamehash());
     // Executes pdftk burst to get all pages separated
     $numpages = emarking_pdf_count_pages($newfilename, $tempdir, false);
     if (!is_numeric($numpages) || $numpages < 1 || $numpagesprevious >= 0 && $numpagesprevious != $numpages) {
         echo $OUTPUT->header();
         echo $OUTPUT->heading(get_string('error'));
         echo $OUTPUT->error_text(get_string('invalidpdfnopages', 'mod_emarking'));
         echo $OUTPUT->continue_button($cancelurl);
         die;
     }
     $exampdfs[] = array('pathname' => $pdffile, 'filename' => $filename);
 }
 $studentsnumber = emarking_get_students_count_for_printing($course->id);
 // A new exam object is created and its attributes filled from form data
 if ($examid == 0) {
     $exam = new stdClass();
Esempio n. 12
0
/**
 * Creates the PDF version (downloadable) of the whole feedback produced by the teacher/tutor
 *
 * @param int $submissionid        	
 * @return boolean
 *
 */
function emarking_multi_create_response_pdf($submission, $student, $context, $cmid)
{
    global $CFG, $DB;
    require_once $CFG->libdir . '/pdflib.php';
    $fs = get_file_storage();
    if (!($pages = $DB->get_records('emarking_page', array('submission' => $submission->id, 'student' => $student->id), 'page ASC'))) {
        return false;
    }
    $emarking = $DB->get_record('emarking', array('id' => $submission->emarking));
    $numpages = count($pages);
    $sqlcomments = "SELECT ec.id,\n\t\t\tec.posx,\n\t\t\tec.posy,\n\t\t\tec.rawtext,\n\t\t\tec.pageno,\n\t\t\tgrm.maxscore,\n\t\t\tec.levelid,\n\t\t\tec.width,\n\t\t\tec.colour,\n\t\t\tec.textformat,\n\t\t\tgrl.score AS score,\n\t\t\tgrl.definition AS leveldesc,\n\t\t\tgrc.id AS criterionid,\n\t\t\tgrc.description AS criteriondesc,\n\t\t\tu.id AS markerid, CONCAT(u.firstname,' ',u.lastname) AS markername\n\t\t\tFROM {emarking_comment} AS ec\n\t\t\tINNER JOIN {emarking_page} AS ep ON (ep.submission = :submission AND ec.page = ep.id)\n\t\t\tLEFT JOIN {user} AS u ON (ec.markerid = u.id)\n\t\t\tLEFT JOIN {gradingform_rubric_levels} AS grl ON (ec.levelid = grl.id)\n\t\t\tLEFT JOIN {gradingform_rubric_criteria} AS grc ON (grl.criterionid = grc.id)\n\t\t\tLEFT JOIN (\n\t\t\tSELECT grl.criterionid, max(score) AS maxscore\n\t\t\tFROM {gradingform_rubric_levels} AS grl\n\t\t\tGROUP BY grl.criterionid\n\t\t\t) AS grm ON (grc.id = grm.criterionid)\n\t\t\tWHERE ec.pageno > 0\n\t\t\tORDER BY ec.pageno";
    $params = array('submission' => $submission->id);
    $comments = $DB->get_records_sql($sqlcomments, $params);
    $commentsperpage = array();
    foreach ($comments as $comment) {
        if (!isset($commentsperpage[$comment->pageno])) {
            $commentsperpage[$comment->pageno] = array();
        }
        $commentsperpage[$comment->pageno][] = $comment;
    }
    // Parameters for PDF generation
    $iconsize = 5;
    $tempdir = emarking_get_temp_dir_path($emarking->id);
    if (!file_exists($tempdir)) {
        mkdir($tempdir);
    }
    // create new PDF document
    $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
    // set document information
    $pdf->SetCreator(PDF_CREATOR);
    $pdf->SetAuthor($student->firstname . ' ' . $student->lastname);
    $pdf->SetTitle($emarking->name);
    $pdf->SetSubject('Exam feedback');
    $pdf->SetKeywords('feedback, emarking');
    $pdf->SetPrintHeader(false);
    $pdf->SetPrintFooter(false);
    // set default header data
    $pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE . ' 036', PDF_HEADER_STRING);
    // set header and footer fonts
    $pdf->setHeaderFont(array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
    $pdf->setFooterFont(array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
    // set default monospaced font
    $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
    // set margins
    $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
    $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
    $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
    // set auto page breaks
    $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
    // set image scale factor
    $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
    // set some language-dependent strings (optional)
    if (@file_exists(dirname(__FILE__) . '/lang/eng.php')) {
        require_once dirname(__FILE__) . '/lang/eng.php';
        $pdf->setLanguageArray($l);
    }
    // ---------------------------------------------------------
    // set font
    $pdf->SetFont('times', '', 16);
    foreach ($pages as $page) {
        // add a page
        $pdf->AddPage();
        // get the current page break margin
        $bMargin = $pdf->getBreakMargin();
        // get current auto-page-break mode
        $auto_page_break = $pdf->getAutoPageBreak();
        // disable auto-page-break
        $pdf->SetAutoPageBreak(false, 0);
        // set bacground image
        $pngfile = $fs->get_file_by_id($page->file);
        $img_file = emarking_get_path_from_hash($tempdir, $pngfile->get_pathnamehash());
        $pdf->Image($img_file, 0, 0, 210, 297, '', '', '', false, 300, '', false, false, 0);
        // restore auto-page-break status
        // $pdf->SetAutoPageBreak($auto_page_break, $bMargin);
        // set the starting point for the page content
        $pdf->setPageMark();
        $widthratio = $pdf->getPageWidth() / 800;
        if (isset($commentsperpage[$page->page])) {
            foreach ($commentsperpage[$page->page] as $comment) {
                $content = $comment->rawtext;
                if ($comment->textformat == 1) {
                    // text annotation
                    $pdf->Annotation($comment->posx * $widthratio, $comment->posy * $widthratio, 6, 6, $content, array('Subtype' => 'Text', 'StateModel' => 'Review', 'State' => 'None', 'Name' => 'Comment', 'NM' => 'Comment' . $comment->id, 'T' => $comment->markername, 'Subj' => 'example', 'C' => array(0, 0, 255)));
                } elseif ($comment->textformat == 2) {
                    $content = $comment->criteriondesc . ': ' . round($comment->score, 1) . '/' . round($comment->maxscore, 1) . "\n" . $comment->leveldesc . "\n" . get_string('comment', 'mod_emarking') . ': ' . $content;
                    // text annotation
                    $pdf->Annotation($comment->posx * $widthratio, $comment->posy * $widthratio, 6, 6, $content, array('Subtype' => 'Text', 'StateModel' => 'Review', 'State' => 'None', 'Name' => 'Comment', 'NM' => 'Mark' . $comment->id, 'T' => $comment->markername, 'Subj' => 'grade', 'C' => array(255, 255, 0)));
                } elseif ($comment->textformat == 3) {
                    $pdf->Image($CFG->dirroot . "/mod/emarking/img/check.gif", $comment->posx * $widthratio, $comment->posy * $widthratio, $iconsize, $iconsize, '', '', '', false, 300, '', false, false, 0);
                } elseif ($comment->textformat == 4) {
                    $pdf->Image($CFG->dirroot . "/mod/emarking/img/crossed.gif", $comment->posx * $widthratio, $comment->posy * $widthratio, $iconsize, $iconsize, '', '', '', false, 300, '', false, false, 0);
                }
            }
        }
    }
    // ---------------------------------------------------------
    // COGIDO PARA IMPRIMIR RÚBRICA
    if ($emarking->downloadrubricpdf) {
        $cm = new StdClass();
        $rubricdesc = $DB->get_recordset_sql("SELECT\n\t\td.name AS rubricname,\n\t\ta.id AS criterionid,\n\t\ta.description ,\n\t\tb.definition,\n\t\tb.id AS levelid,\n\t\tb.score,\n\t\tIFNULL(E.id,0) AS commentid,\n\t\tIFNULL(E.pageno,0) AS commentpage,\n\t\tE.rawtext AS commenttext,\n\t\tE.markerid AS markerid,\n\t\tIFNULL(E.textformat,2) AS commentformat,\n\t\tIFNULL(E.bonus,0) AS bonus,\n\t\tIFNULL(er.id,0) AS regradeid,\n\t\tIFNULL(er.motive,0) AS motive,\n\t\ter.comment AS regradecomment,\n\t\tIFNULL(er.markercomment, '') AS regrademarkercomment,\n\t\tIFNULL(er.accepted,0) AS regradeaccepted\n\t\tFROM {course_modules} AS c\n\t\tINNER JOIN {context} AS mc ON (c.id = :coursemodule AND c.id = mc.instanceid)\n\t\tINNER JOIN {grading_areas} AS ar ON (mc.id = ar.contextid)\n\t\tINNER JOIN {grading_definitions} AS d ON (ar.id = d.areaid)\n\t\tINNER JOIN {gradingform_rubric_criteria} AS a ON (d.id = a.definitionid)\n\t\tINNER JOIN {gradingform_rubric_levels} AS b ON (a.id = b.criterionid)\n\t\tLEFT JOIN (\n\t\tSELECT ec.*, es.id AS submissionid\n\t\tFROM {emarking_comment} AS ec\n\t\tINNER JOIN {emarking_page} AS ep ON (ec.page = ep.id)\n\t\tINNER JOIN {emarking_draft} AS es ON (es.id = :submission AND ep.submission = es.id)\n\t\t) AS E ON (E.levelid = b.id)\n\t\tLEFT JOIN {emarking_regrade} AS er ON (er.criterion = a.id AND er.submission = E.submissionid)\n\t\tORDER BY a.sortorder ASC, b.score ASC", array('coursemodule' => $cmid, 'submission' => $submission->id));
        $table = new html_table();
        $data = array();
        foreach ($rubricdesc as $rd) {
            if (!isset($data[$rd->criterionid])) {
                $data[$rd->criterionid] = array($rd->description, $rd->definition . " (" . round($rd->score, 2) . " ptos. )");
            } else {
                array_push($data[$rd->criterionid], $rd->definition . " (" . round($rd->score, 2) . " ptos. )");
            }
        }
        $table->data = $data;
        // add extra page with rubrics
        $pdf->AddPage();
        $pdf->Write(0, 'Rúbrica', '', 0, 'L', true, 0, false, false, 0);
        $pdf->SetFont('helvetica', '', 8);
        $tbl = html_writer::table($table);
        $pdf->writeHTML($tbl, true, false, false, false, '');
    }
    // ---------------------------------------------------------
    $pdffilename = 'response_' . $emarking->id . '_' . $student->id . '.pdf';
    $pathname = $tempdir . '/' . $pdffilename;
    if (@file_exists($pathname)) {
        unlink($pathname);
    }
    // Close and output PDF document
    $pdf->Output($pathname, 'F');
    // Copiar archivo desde temp a Área
    $file_record = array('contextid' => $context->id, 'component' => 'mod_emarking', 'filearea' => 'response', 'itemid' => $student->id, 'filepath' => '/', 'filename' => $pdffilename, 'timecreated' => time(), 'timemodified' => time(), 'userid' => $student->id, 'author' => $student->firstname . ' ' . $student->lastname, 'license' => 'allrightsreserved');
    // Si el archivo ya existía entonces lo borramos
    if ($fs->file_exists($context->id, 'mod_emarking', 'response', $student->id, '/', $pdffilename)) {
        $previousfile = $fs->get_file($context->id, 'mod_emarking', 'response', $student->id, '/', $pdffilename);
        $previousfile->delete();
    }
    $fileinfo = $fs->create_file_from_pathname($file_record, $pathname);
    return true;
}