function view()
 {
     global $CFG, $USER, $DB, $OUTPUT, $PAGE;
     $edit = optional_param('edit', 0, PARAM_BOOL);
     $saved = optional_param('saved', 0, PARAM_BOOL);
     $print = optional_param('print', 0, PARAM_BOOL);
     $context = context_module::instance($this->cm->id);
     require_capability('mod/assignment:view', $context);
     $submission = $this->get_submission();
     //We added an extra field to the submissions table, for feedback using video or audio
     //and this was where we added it. But we will no longer do this in PoodLL 2. It was hacky.
     //can just drop in a video from a recording repo if want to do this.  But never say never so
     //am leaving the code around. Justin 20120302
     if (false && $submission) {
         $dbman = $DB->get_manager();
         $table = new xmldb_table('assignment_submissions');
         if (!$dbman->field_exists($table, 'poodllfeedback')) {
             $field = new xmldb_field('poodllfeedback', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null);
             $result = $dbman->add_field($table, $field);
         }
     }
     //Justin
     //Are we printing this or not
     if ($print) {
         if (TCPPDF_OLD) {
             require_once $CFG->libdir . '/tcpdf/tcpdf.php';
         } else {
             require_once $CFG->libdir . '/newtcpdf/tcpdf.php';
         }
         $pdf = new tcpdf(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true);
         // remove default header/footer
         //old version of tcppdf
         if (TCPPDF_OLD) {
             $pdf->print_header = false;
             $pdf->print_footer = false;
         } else {
             //new version of tcppdf
             $pdf->setPrintHeader(false);
             $pdf->setPrintFooter(false);
         }
         //set margins
         $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
         //set auto page breaks
         $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
         $pdf->setFont('freeserif', '', 10);
         //make page
         $pdf->AddPage();
         //prepare html content
         $options = new object();
         $options->smiley = false;
         $options->filter = false;
         $strHtml = format_text($submission->data1, FORMAT_HTML, $options);
         //print the thing
         $pdf->writeHTML($strHtml, true, 0, true, 0);
         //The I is for inline, meaning tell the browser to shopw not download it.
         $pdf->output('document.pdf', 'I');
         //$pdf->output();
         return;
     }
     //Guest can not submit nor edit an assignment (bug: 4604)
     if (!has_capability('mod/assignment:submit', $context)) {
         $editable = null;
     } else {
         $editable = $this->isopen() && (!$submission || $this->assignment->resubmit || !$submission->timemarked);
     }
     //modify Justin 20090305, we don't want to add this extra step for users.
     //If they can edit, and they haven't submitted anything, then lets just show the form.
     //If they have submitted something, lets give them an extra step if ytthey want to submit
     //to protect accidental overwrite of their submission.
     // $editmode = ($editable and $edit);
     $editmode = ($editable and !$submission || $edit);
     if ($editmode) {
         //guest can not edit or submit assignment
         if (!has_capability('mod/assignment:submit', $context)) {
             print_error('guestnosubmit', 'assignment');
         }
     }
     add_to_log($this->course->id, "assignment", "view", "view.php?id={$this->cm->id}", $this->assignment->id, $this->cm->id);
     /// prepare form and process submitted data
     //load it with some info it needs to determine the params for PoodLL recorder.
     //for voice then text, we need to know if we already have voice or not
     if (empty($submission)) {
         $mediapath = "";
     } else {
         $mediapath = $submission->data2;
     }
     $data = new stdClass();
     $data->id = $this->cm->id;
     $data->edit = 1;
     if ($submission) {
         $data->sid = $submission->id;
         $data->text = $submission->data1;
         $data->textformat = FORMAT_HTML;
     } else {
         $data->sid = NULL;
         $data->text = '';
         $data->textformat = FORMAT_HTML;
     }
     $editoroptions = array('noclean' => false, 'maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes' => $this->course->maxbytes, 'context' => $this->context);
     $data = file_prepare_standard_editor($data, 'text', $editoroptions, $this->context, 'mod_assignment', $this->filearea, $data->sid);
     $mform = new mod_assignment_poodllonline_edit_form(null, array("cm" => $this->cm, "assignment" => $this->assignment, "mediapath" => $mediapath, "data" => $data, "editoroptions" => $editoroptions));
     if ($mform->is_cancelled()) {
         redirect($PAGE->url);
     }
     if ($data = $mform->get_data()) {
         $submission = $this->get_submission($USER->id, true);
         //create the submission if needed & its id
         //this step is only required if we are using a text editor, it is to move drft files over Justin 20120208
         if ($this->assignment->var3 == OM_REPLYTEXTONLY) {
             $data = file_postupdate_standard_editor($data, 'text', $editoroptions, $this->context, 'mod_assignment', $this->filearea, $submission->id);
         }
         $submission = $this->update_submission($data);
         //TODO fix log actions - needs db upgrade
         add_to_log($this->course->id, 'assignment', 'upload', 'view.php?a=' . $this->assignment->id, $this->assignment->id, $this->cm->id);
         $this->email_teachers($submission);
         //redirect to get updated submission date and word count
         redirect(new moodle_url($PAGE->url, array('saved' => 1)));
     }
     /// print header, etc. and display form if needed
     if ($editmode) {
         $this->view_header(get_string('editmysubmission', 'assignment'));
     } else {
         $this->view_header();
     }
     $this->view_intro();
     $this->view_dates();
     if ($saved) {
         notify(get_string('submissionsaved', 'assignment'), 'notifysuccess');
     }
     if (has_capability('mod/assignment:submit', $context)) {
         echo $OUTPUT->box_start('generalbox boxaligncenter', 'poodllonline');
         // print_simple_box_start('center', '70%', '', 0, 'generalbox', 'poodllonline');
         if ($editmode) {
             if ($submission) {
                 //Show our  students answer box
                 echo get_string('mysubmission', 'assignment_poodllonline');
                 echo $OUTPUT->box_start('generalbox boxaligncenter', 'mysubmission');
                 //print_simple_box_start('center', '50%', '', 0, 'generalbox', 'mysubmission');
                 echo $this->fetchResponses($this->context->id, $submission->id, $this->assignment->var3, $submission->data1, $submission->data2, false, false, false);
                 //Close our students answer box
                 //print_simple_box_end();
                 echo $OUTPUT->box_end();
             }
             $mform->display();
         } else {
             if ($submission) {
                 //Show our  students answer box
                 echo get_string('mysubmission', 'assignment_poodllonline');
                 echo $OUTPUT->box_start('generalbox boxaligncenter', 'mysubmission');
                 //print_simple_box_start('center', '50%', '', 0, 'generalbox', 'mysubmission');
                 echo $this->fetchResponses($this->context->id, $submission->id, $this->assignment->var3, $submission->data1, $submission->data2, false, false, false);
                 //Close out students answer box
                 //print_simple_box_end();
                 echo $OUTPUT->box_end();
             } else {
                 if (!has_capability('mod/assignment:submit', $context)) {
                     //fix for #4604
                     echo '<div style="text-align:center">' . get_string('guestnosubmit', 'assignment') . '</div>';
                 } else {
                     if ($this->isopen()) {
                         //fix for #4206
                         echo '<div style="text-align:center">' . get_string('emptysubmission', 'assignment') . '</div>';
                     }
                 }
             }
         }
         // print_simple_box_end();
         echo $OUTPUT->box_end();
         if (!$editmode && $editable) {
             echo "<div style='text-align:center'>";
             //this method is deprecated , we now use $OUTPUT  Justin 20110602
             //  print_single_button('view.php', array('id'=>$this->cm->id,'edit'=>'1'),
             //          get_string('editmysubmission', 'assignment'));
             echo $OUTPUT->single_button('view.php?id=' . $this->cm->id . '&edit=1', get_string('editmysubmission', 'assignment'));
             echo "</div>";
         }
         //show a print buttonif it is text only and not edit mode
         if ($this->assignment->var3 == OM_REPLYTEXTONLY && !$editmode) {
             echo "<br /><div style='text-align:center'>";
             echo "<a href='view.php?id=" . $this->cm->id . "&print=1' target='_new'>" . get_string('printthissubmission', 'assignment_poodllonline') . "</a>";
             //The target tag is ignored by print_single_button so not using it
             //print_single_button('view.php', array('id'=>$this->cm->id,'print'=>'1'),get_string('printthissubmission', 'assignment_poodllonline'),'get','_new');
             echo "</div>";
         }
         //end of if printable
     }
     //end of if can submit
     $this->view_feedback();
     $this->view_footer();
 }
Example #2
0
 function view()
 {
     global $CFG, $USER;
     $edit = optional_param('edit', 0, PARAM_BOOL);
     $saved = optional_param('saved', 0, PARAM_BOOL);
     $print = optional_param('print', 0, PARAM_BOOL);
     $context = get_context_instance(CONTEXT_MODULE, $this->cm->id);
     require_capability('mod/assignment:view', $context);
     $submission = $this->get_submission();
     //We need to add an extra field to the submissions table, for feedback using video or audio
     //we check if it exists here, and if not we add it. Justin 20100324
     if ($submission) {
         if (!column_type('assignment_submissions', 'poodllfeedback')) {
             // add field to store media comments (audio or video) filename to students submissions
             $sql = "ALTER TABLE " . $CFG->prefix . "assignment_submissions ADD poodllfeedback TEXT";
             $result = execute_sql($sql);
         }
     }
     //Justin
     //Are we printing this or not
     if ($print) {
         if (TCPPDF_OLD) {
             require_once $CFG->libdir . '/tcpdf/tcpdf.php';
         } else {
             require_once $CFG->libdir . '/newtcpdf/tcpdf.php';
         }
         $pdf = new tcpdf(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true);
         // remove default header/footer
         //old version of tcppdf
         if (TCPPDF_OLD) {
             $pdf->print_header = false;
             $pdf->print_footer = false;
         } else {
             //new version of tcppdf
             $pdf->setPrintHeader(false);
             $pdf->setPrintFooter(false);
         }
         //set margins
         $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
         //set auto page breaks
         $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
         $pdf->setFont('freeserif', '', 10);
         //make page
         $pdf->AddPage();
         //prepare html content
         $options = new object();
         $options->smiley = false;
         $options->filter = false;
         $strHtml = format_text($submission->data1, FORMAT_HTML, $options);
         //print the thing
         $pdf->writeHTML($strHtml, true, 0, true, 0);
         //The I is for inline, meaning tell the browser to shopw not download it.
         $pdf->output('document.pdf', 'I');
         //$pdf->output();
         return;
     }
     //Guest can not submit nor edit an assignment (bug: 4604)
     if (!has_capability('mod/assignment:submit', $context)) {
         $editable = null;
     } else {
         $editable = $this->isopen() && (!$submission || $this->assignment->resubmit || !$submission->timemarked);
     }
     //modify Justin 20090305, we don't want to add this extra step for users.
     //If they can edit, and they haven't submitted anything, then lets just show the form.
     //If they have submitted something, lets give them an extra step if ytthey want to submit
     //to protect accidental overwrite of their submission.
     // $editmode = ($editable and $edit);
     $editmode = ($editable and !$submission || $edit);
     if ($editmode) {
         //guest can not edit or submit assignment
         if (!has_capability('mod/assignment:submit', $context)) {
             print_error('guestnosubmit', 'assignment');
         }
     }
     add_to_log($this->course->id, "assignment", "view", "view.php?id={$this->cm->id}", $this->assignment->id, $this->cm->id);
     /// prepare form and process submitted data
     //load it with some info it needs to determine the params for chosho recorder.
     //for voice then text, we need to know if we already have voice or not
     if (empty($submission)) {
         $mediapath = "";
     } else {
         $mediapath = $submission->data2;
     }
     $mform = new mod_assignment_poodllonline_edit_form(null, array("cm" => $this->cm, "assignment" => $this->assignment, "mediapath" => $mediapath));
     $defaults = new object();
     $defaults->id = $this->cm->id;
     if (!empty($submission)) {
         //we always use html editor: Justin 20090225
         //if ($this->usehtmleditor) {
         if (true) {
             $options = new object();
             $options->smiley = false;
             $options->filter = false;
             $defaults->text = format_text($submission->data1, FORMAT_HTML, $options);
             $defaults->format = FORMAT_HTML;
         } else {
             $defaults->text = $submission->data1;
             $defaults->format = $submission->data2;
         }
     }
     $mform->set_data($defaults);
     if ($mform->is_cancelled()) {
         redirect('view.php?id=' . $this->cm->id);
     }
     if ($data = $mform->get_data()) {
         // No incoming data?
         if ($editable && $this->update_submission($data)) {
             //TODO fix log actions - needs db upgrade
             $submission = $this->get_submission();
             add_to_log($this->course->id, 'assignment', 'upload', 'view.php?a=' . $this->assignment->id, $this->assignment->id, $this->cm->id);
             $this->email_teachers($submission);
             //redirect to get updated submission date and word count
             redirect('view.php?id=' . $this->cm->id . '&saved=1');
         } else {
             // TODO: add better error message
             notify(get_string("error"));
             //submitting not allowed!
         }
     }
     /// print header, etc. and display form if needed
     if ($editmode) {
         $this->view_header(get_string('editmysubmission', 'assignment'));
     } else {
         $this->view_header();
     }
     $this->view_intro();
     $this->view_dates();
     if ($saved) {
         notify(get_string('submissionsaved', 'assignment'), 'notifysuccess');
     }
     if (has_capability('mod/assignment:submit', $context)) {
         print_simple_box_start('center', '70%', '', 0, 'generalbox', 'poodllonline');
         if ($editmode) {
             if ($submission) {
                 //Show our  students answer box
                 echo get_string('mysubmission', 'assignment_poodllonline');
                 print_simple_box_start('center', '50%', '', 0, 'generalbox', 'mysubmission');
                 //check if we need media output
                 switch ($this->assignment->var3) {
                     case OM_REPLYVOICEONLY:
                         //format and echo text that our Audio filter will pick and show in a player
                         //needs to be formatted as html for filter to pick it up
                         //echo format_text('{FMS:VOICE='.	$submission->data2.'}', FORMAT_HTML);
                         echo format_text('{POODLL:type=audio,path=' . $submission->data2 . ',protocol=rtmp}', FORMAT_HTML);
                         break;
                     case OM_REPLYVIDEOONLY:
                         //format and echo text that our Video filter will pick and show in a player
                         //needs to be formatted as html for filter to pick it up
                         //echo format_text('{FMS:VIDEO='.	$submission->data2.'}', FORMAT_HTML);
                         echo format_text('{POODLL:type=video,path=' . $submission->data2 . ',protocol=rtmp}', FORMAT_HTML);
                         break;
                     case OM_REPLYVOICETHENTEXT:
                         //format and echo text that our Audio filter will pick and show in a player
                         //needs to be formatted as html for filter to pick it up
                         //echo format_text('{FMS:VOICE='.	$submission->data2.'}', FORMAT_HTML);
                         echo format_text('{POODLL:type=audio,path=' . $submission->data2 . ',protocol=rtmp}', FORMAT_HTML);
                         break;
                     case OM_REPLYVIDEOTHENTEXT:
                         //format and echo text that our Video filter will pick and show in a player
                         //needs to be formatted as html for filter to pick it up
                         //echo format_text('{FMS:VIDEO='.	$submission->data2.'}', FORMAT_HTML);
                         echo format_text('{POODLL:type=video,path=' . $submission->data2 . ',protocol=rtmp}', FORMAT_HTML);
                         break;
                 }
                 //check if we need text output
                 switch ($this->assignment->var3) {
                     case OM_REPLYVOICETHENTEXT:
                     case OM_REPLYVIDEOTHENTEXT:
                         if (empty($submission->data1)) {
                             break;
                         } else {
                             echo "<br />";
                         }
                     case OM_REPLYTEXTONLY:
                     default:
                         echo format_text($submission->data1, FORMAT_HTML);
                 }
                 //Close our students answer box
                 print_simple_box_end();
             }
             $mform->display();
         } else {
             if ($submission) {
                 //Show our  students answer box
                 echo get_string('mysubmission', 'assignment_poodllonline');
                 print_simple_box_start('center', '50%', '', 0, 'generalbox', 'mysubmission');
                 switch ($this->assignment->var3) {
                     case OM_REPLYVOICEONLY:
                         //format and echo text that our Audio filter will pick and show in a player
                         //needs to be formatted as html for filter to pick it up
                         //echo format_text('{FMS:VOICE='.	$submission->data2.'}', FORMAT_HTML);
                         echo format_text('{POODLL:type=audio,path=' . $submission->data2 . ',protocol=rtmp}', FORMAT_HTML);
                         break;
                     case OM_REPLYVIDEOONLY:
                         //format and echo text that our Video filter will pick and show in a player
                         //needs to be formatted as html for filter to pick it up
                         //echo format_text('{FMS:VIDEO='.	$submission->data2.'}', FORMAT_HTML);
                         echo format_text('{POODLL:type=video,path=' . $submission->data2 . ',protocol=rtmp}', FORMAT_HTML);
                         break;
                     case OM_REPLYVOICETHENTEXT:
                         //format and echo text that our Audio filter will pick and show in a player
                         //needs to be formatted as html for filter to pick it up
                         //echo format_text('{FMS:VOICE='.	$submission->data2.'}', FORMAT_HTML);
                         echo format_text('{POODLL:type=audio,path=' . $submission->data2 . ',protocol=rtmp}', FORMAT_HTML);
                         break;
                     case OM_REPLYVIDEOTHENTEXT:
                         //format and echo text that our Video filter will pick and show in a player
                         //needs to be formatted as html for filter to pick it up
                         //echo format_text('{FMS:VIDEO='.	$submission->data2.'}', FORMAT_HTML);
                         echo format_text('{POODLL:type=video,path=' . $submission->data2 . ',protocol=rtmp}', FORMAT_HTML);
                         break;
                 }
                 //check if we need text output
                 switch ($this->assignment->var3) {
                     case OM_REPLYVOICETHENTEXT:
                     case OM_REPLYVIDEOTHENTEXT:
                         if (empty($submission->data1)) {
                             break;
                         } else {
                             echo "<br />";
                         }
                     case OM_REPLYTEXTONLY:
                     default:
                         echo format_text($submission->data1, FORMAT_HTML);
                 }
                 //Close out students answer box
                 print_simple_box_end();
             } else {
                 if (!has_capability('mod/assignment:submit', $context)) {
                     //fix for #4604
                     echo '<div style="text-align:center">' . get_string('guestnosubmit', 'assignment') . '</div>';
                 } else {
                     if ($this->isopen()) {
                         //fix for #4206
                         echo '<div style="text-align:center">' . get_string('emptysubmission', 'assignment') . '</div>';
                     }
                 }
             }
         }
         print_simple_box_end();
         if (!$editmode && $editable) {
             echo "<div style='text-align:center'>";
             print_single_button('view.php', array('id' => $this->cm->id, 'edit' => '1'), get_string('editmysubmission', 'assignment'));
             echo "</div>";
         }
         //show a print buttonif it is text only and not edit mode
         if ($this->assignment->var3 == OM_REPLYTEXTONLY && !$editmode) {
             echo "<br /><div style='text-align:center'>";
             echo "<a href='view.php?id=" . $this->cm->id . "&print=1' target='_new'>" . get_string('printthissubmission', 'assignment_poodllonline') . "</a>";
             //The target tag is ignored by print_single_button so not using it
             //print_single_button('view.php', array('id'=>$this->cm->id,'print'=>'1'),get_string('printthissubmission', 'assignment_poodllonline'),'get','_new');
             echo "</div>";
         }
         //end of if printable
     }
     //end of if can submit
     $this->view_feedback();
     $this->view_footer();
 }
 /**
  * @param null $id
  * @return \Cake\Network\Response|null
  *
  * This function will produce PDF output to display a Teaching Plan.
  *
  * Said Plan is composed of the following sections:
  * 1. A cover sheet.
  * 2. Zero or more full-sized plan element listings (PEL).
  * 3. One short-form PEL.
  * 4. A rear cover sheet.
  *
  * A plan starts as a sequence of A4 sized pages.  Henceforth a "page"
  * will specifically refer to an A4 sized page.
  *
  * The front and rear cover sheets are ordinary pages.
  *
  * Each PEL is a sequence of two pages, a left-side and a right-side,
  * intended to be viewed side-by-side.
  * A PEL contains up to 5 Plan Elements, listed from top-to-bottom, with
  * the exception of the final short-form PEL.
  *
  * The short-form PEL only contains 4 Plan Elements.  Where the 5th Element
  * would normally be printed, the short-form PEL contains a blank area for the
  * left page, and a signature block for the right page.
  *
  * Physical Paper:
  *
  * With suitable software, the pages can be printed in booklet form, on double-sized
  * paper, with four pages per physical sheet of paper, two pages on each side. This
  * closely simulates the original hand-drawn form in pre-printed booklets. The downsides
  * of this method include:
  *
  *  * We need to find large paper and a printer that can print on both sides of it.
  *  * We need to find suitable booklet printing software and expertise.
  *  * There's also quite a lot of wasted form-space.
  *
  * We can also print these pages sequentially, on the front and back of A4 paper.
  * If we do this then the PELs can be readily viewed as intended, side-by-side, simply
  * by turning the pages.
  *
  * The downside of this method is that it's such a good idea, within its narrow context,
  * and so radically different from the original form, that the Bureacratic Gods that
  * lurk in the shadows must certainly frown upon this approach.  Nevertheless, I hereby taunt fate,
  * live dangerously, and chose this method.  May the Gods of Idiocy strike me down!
  */
 public function pdf($id = null)
 {
     // 1. In the beginning...
     // 1.1 Obtain the data to print.
     // 1.1.1 We'll obviously need info about the teaching plan itself, as well as
     // its associated elements
     $tplan_id = $id;
     $tplan = $this->Tplans->get($tplan_id, ['contain' => 'TplanElements']);
     // 1.1.2 Get the front cover info.
     // This query finds all sections that use this teaching plan. Most of the selected
     // fields should be the same, such as the course title, teacher, and teaching_hours_per_class.
     // However, the cohorts should all be different. (This would be nice to verify.)
     $tableSections = TableRegistry::get('Sections');
     $query = $tableSections->find('all')->contain(['Cohorts.Majors', 'Semesters', 'Subjects', 'Teachers'])->order('Cohorts.seq')->where(['Sections.tplan_id' => $tplan_id]);
     $cohortList = null;
     foreach ($query as $tplanUser) {
         $cohortNickname = $tplanUser->cohort->nickname;
         is_null($cohortList) ? $cohortList = $cohortNickname : ($cohortList .= ',' . $cohortNickname);
     }
     // Assuming all of these fields are the same, for each record,
     // then its ok to retrieve their values from the 1st record.
     // WARNING! Maybe they're not all the same!
     $n = $query->first();
     $info['subject'] = $n->subject->title;
     $info['major'] = $n->cohort->major->title;
     $info['cohorts'] = $cohortList;
     $info['instructor'] = $n->teacher->fam_name;
     $info['class_cnt'] = $tplan['session_cnt'];
     $info['teaching_hrs_per_class'] = $n->thours;
     // The desired semester sequence printed, is the reverse of
     // what's in the db.
     $info['semester_seq'] = ($n->semester->seq = 1) ? 2 : 1;
     // Ugly, ad-hoc bureaucratise...
     $info['book'] = $tplan->book;
     // 1.1.4. Now get the plan elements
     $info['elements'] = [];
     foreach ($tplan->tplan_elements as $tplanElement) {
         $element = ['start_thour' => $tplanElement->start_thour, 'stop_thour' => $tplanElement->stop_thour, 'col1' => $tplanElement->col1, 'col2' => $tplanElement->col2, 'col3' => $tplanElement->col3, 'col4' => $tplanElement->col4];
         $info['elements'][] = $element;
     }
     // 2. Initialize the pdf
     require 'tcpdf.php';
     // The primary method of specifying position is to measure mm from the origin,
     // where the origin is at the upper-left corner of the paper, moving right increases x
     // and moving down increases y.
     $pdf = new \tcpdf('P', 'mm', 'A4');
     $pdf->SetFont('cid0cs', '', 16, '', true);
     // remove default header/footer
     $pdf->setPrintHeader(false);
     $pdf->setPrintFooter(false);
     // 3. Page 1, The cover
     $pdf->AddPage();
     $this->emitFrontCover($info, $pdf, 10, 10);
     // 4. The Plan Elements
     //
     // We can print the PELs, double-side, on ordinary paper, or we can do it
     // booklet-style on large paper. You decide.
     $bookletStyle = false;
     if ($bookletStyle) {
         // Upon careful reflection we can determine that:
         // 1. Any plan containing <=4 plan elements can be fully printed on a single short-form PEL.
         // 2. Each additional sheet of paper will accommodate up to 10 additional plan elements.
         // Our basic strategy will be to determine how many extra sheets of paper are required
         // and then emit 10 (plan elements or blank elements) to fill each extra sheet.
         // Then continue to emit 10 () to fill the final set of two-pages.
         $tplanElementCnt = count($info['elements']);
         $extraSheetCnt = intval(($tplanElementCnt + 5) / 10);
         // model this in excel and see that it works
         $tplanElementIdx = 0;
         while ($extraSheetCnt > 0) {
             // emit the next 10 (plan elements or blank elements)
             $tplanElementIdx += $this->emitPEL($info, $pdf, $tplanElementIdx, false);
             $extraSheetCnt--;
         }
         $tplanElementIdx += $this->emitPEL($info, $pdf, $tplanElementIdx, true);
     } else {
         // Excellent choice.  Let's print these pages, double-sided, on ordinary paper.
         $tplanElementCnt = count($info['elements']);
         $tplanElementIdx = 0;
         // which element to print next? zero based idx.
         // Emit all the full-sized PELs, if any.
         while ($tplanElementCnt - $tplanElementIdx >= 5) {
             // emit the next 5 plan elements
             $tplanElementIdx += $this->emitPEL($info, $pdf, $tplanElementIdx, false);
             // not last PEL
         }
         // Always emit at least one short-form PEL.
         $tplanElementIdx += $this->emitPEL($info, $pdf, $tplanElementIdx, true);
         // last PEL
     }
     // 5. Rear cover
     $pdf->AddPage();
     $this->emitRearCover($pdf, 17, 23);
     $pdf->Output();
     $this->response->type('application/pdf');
     return $this->response;
 }
 public function attend($id = null)
 {
     require 'tcpdf.php';
     // 1. We'll need some info about this section, to print on the form
     $section = $this->Sections->get($id, ['contain' => ['Cohorts.Majors', 'Semesters', 'Subjects', 'Teachers']]);
     // 2. And we'll need some info about the students.
     /* @var \Cake\Database\Connection $connection */
     $connection = ConnectionManager::get('default');
     $query = "SELECT sid, fam_name, giv_name from students\n            left join cohorts  on students.cohort_id=cohorts.id\n            left join sections on cohorts.id=sections.cohort_id\n            where sections.id={$id} order by sid";
     $classRoster = $connection->execute($query)->fetchAll('assoc');
     // This query collects attendance info, in sid order. Other queries collect
     // other info, also in sid order. Be careful to ensure that each query contains
     // exactly the same students.
     // |--------------|--|
     // | students.sid |
     /* @var \Cake\Database\Connection $connection */
     $connection = ConnectionManager::get('default');
     $query = "select week, sid, itype_id, participate from interactions \nleft join clazzes on interactions.clazz_id=clazzes.id\nleft join sections on clazzes.section_id=sections.id\nleft join students on interactions.student_id=students.id\nwhere sections.id={$id} and clazzes.exam != 1";
     $interactionResults = $connection->execute($query)->fetchAll('assoc');
     // Now merge $attendResults and $classRoster into some useable format
     foreach ($interactionResults as $interaction) {
         foreach ($classRoster as $student_idx => $student) {
             if ($student['sid'] == $interaction['sid']) {
                 $w = $interaction['week'];
                 $widx = $w - 1;
                 // convert to zero based week
                 if ($interaction['itype_id'] == "1") {
                     $classRoster[$student_idx]['weeks'][$widx]['a'] = 1;
                 } else {
                     if ($interaction['itype_id'] == "4") {
                         $classRoster[$student_idx]['weeks'][$widx]['b'] = $interaction['participate'];
                     } else {
                         // Another kind of interaction type has been found.
                         // What should we do?
                     }
                 }
             } else {
                 // An interaction has been found for a student who's not really in this class.
                 // What should we do?
             }
         }
     }
     // The primary method of specifying position is to measure mm from the origin,
     // where the origin is at the upper-left corner of the paper, moving right increases x
     // and moving down increases y. We will also use a 2nd level of positioning, described
     // shortly, on top of this level one positioning.
     $pdf = new \tcpdf('L', 'mm', 'a4');
     $pdf->SetFont('cid0cs', '', 16, '', true);
     // remove default header/footer
     $pdf->setPrintHeader(false);
     $pdf->setPrintFooter(false);
     $pdf->AddPage();
     $this->emitAttendForm($pdf, $section, $classRoster, 0);
     $pdf->AddPage();
     $this->emitAttendForm($pdf, $section, $classRoster, 30);
     $pdf->Output();
     $this->response->type('application/pdf');
     return $this->response;
 }