[opw-web] Add the functionality to get an archive of signed contracts for a program



commit b95caf241a5da1b62de52cb068c61ba3d9fe87b7
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Sun Jun 14 13:55:05 2015 -0400

    Add the functionality to get an archive of signed contracts for a program
    
    For auditing purposes, it's useful to have a permanent, offline record
    of the signed contracts for a round. Add a link from "view participants"
    that allows downloading a zipfile of PDFs, where each PDF shows the
    contract that the user signed with the time they signed it and the
    name they entered.

 lang/en-gb.php                                     |    1 +
 modules/mod_contract.php                           |   95 ++++++++++++++++++++
 modules/mod_view_participants.php                  |    1 +
 skins/easterngreen/html/tpl_view_participants.html |    1 +
 4 files changed, 98 insertions(+), 0 deletions(-)
---
diff --git a/lang/en-gb.php b/lang/en-gb.php
index 587f6ff..6a0efa2 100644
--- a/lang/en-gb.php
+++ b/lang/en-gb.php
@@ -334,6 +334,7 @@ $lang_data = array(
     'uploaded'              => 'Uploaded',
     'no_participants'       => 'This programs has no participants',
     'projects'              => 'Projects',
+    'contract_archive'      => 'Contract archive',
 
     /* Module: notifications */
     'notification_mails'    => 'Notification mails',
diff --git a/modules/mod_contract.php b/modules/mod_contract.php
index 4adc52a..325270b 100644
--- a/modules/mod_contract.php
+++ b/modules/mod_contract.php
@@ -81,6 +81,101 @@ if ($action == 'edit_student' || $action == 'edit_mentor') {
     // Output the module
     $module_title = $lang->get('edit_contract');
     $module_data = $skin->output('tpl_edit_contract');
+} else if ($action == 'archive') {
+    // Get all the contracts for a program as a zip-file archive of PDF files
+
+    $user->restrict($user->is_admin);
+
+    // We require this after checking for admin status to reduce any security exposure
+    require_once('tcpdf/tcpdf.php');
+
+    // Find all the participants for this program that have signed contracts
+    $sql = "SELECT r.*, pf.fullname, pf.email, " .
+           "EXISTS (SELECT * from {$db->prefix}participants prt " .
+               "LEFT JOIN {$db->prefix}projects prj " .
+               "ON prj.id = prt.project_id " .
+               "WHERE prt.program_id = r.program_id AND prt.username = r.username AND prj.is_accepted = 1) 
as has_project " .
+           "FROM {$db->prefix}roles r " .
+           "LEFT JOIN {$db->prefix}profiles pf on pf.username = r.username " .
+           "WHERE contract_accepted_time != 0 AND program_id = :program_id";
+
+    $role_data = $db->query($sql,
+                            array('program_id' => $program_id));
+
+    // Avoid looking up the same contract multiple times from the database
+    $contracts_by_id = array();
+
+    $zipfile = new ZipArchive;
+    $zipname = tempnam("/tmp", "contracts_archive");
+    $zipfile->open($zipname, ZipArchive::CREATE);
+
+    $folder_name = preg_replace("/\W+/", "_", $program_data["title"]);
+
+    foreach ($role_data as $row)
+    {
+        $contract_id = $row['contract_id'];
+        if (!array_key_exists($contract_id, $contracts_by_id)) {
+            $sql = "select contents from {$db->prefix}contracts " .
+                   "WHERE id = ?";
+            $contract_row = $db->query($sql, $row['contract_id'], true);
+            $markdown = $contract_row['contents'];;
+            $contract_htmlhtml = Michelf\Markdown::defaultTransform($markdown);
+            $contracts_by_id[$contract_id] = Michelf\Markdown::defaultTransform($markdown);
+        }
+
+        $pdf = new TCPDF('P', 'in', 'USLETTER',
+                         true /*unicode */, 'UTF-8', false /* !PDF/A */);
+        $pdf->SetMargins(0.5, 0.5, 0.5); /* left, top, right, margin */
+        $pdf->setFooterMargin(0.5);
+        $pdf->setHeaderMargin(0.5);
+        $pdf->SetAutoPageBreak(TRUE, 0.75 /* bottom margin */);
+        $pdf->setFontSubsetting(true);
+        $pdf->setPrintHeader(false);
+        $pdf->setPrintFooter(true);
+
+        $pdf->AddPage();
+
+        $pdf->SetFontSize(13);
+        $pdf->SetFont('helvetica', 'B');
+
+        $pdf->write(0, $program_data["title"] . "\n");
+
+        $pdf->SetFontSize(11);
+        $pdf->SetFont('helvetica', '');
+        $pdf->write(0, "Full name: " . $row["fullname"] . "\n");
+        $pdf->write(0, "Username: " . $row["username"] . "\n");
+        $pdf->write(0, "Role: " . get_role_string($row['role'], $row['has_project']) . "\n");
+        $pdf->write(0, "Email: " . $row["email"] . "\n");
+        $pdf->write(0, "\n");
+
+        // Show the contract text in a shaded box at a smaller size
+        $html = Michelf\Markdown::defaultTransform($contracts_by_id[$contract_id]);
+        $pdf->SetFontSize(9);
+        $pdf->SetFillColor(255, 250, 240);
+        $pdf->SetDrawColor(128, 125, 120);
+        $pdf->writeHTMLCell(0, 0, '', '',
+                            $html,
+                            1 /*border */, 1 /* position on next line afterwards */, true /* fill */);
+
+        // Now show the signature information
+        $pdf->SetFontSize(11);
+        $pdf->write(0, "\n");
+        $pdf->write(0, 'E-Signed by "' . $row['contract_entered_name'] . '" on ' . date('M d, Y h:m:s', 
$row['contract_accepted_time']) . ' using ' .$config->site_url);
+
+        // Insert into the archive
+        $zipfile->addFromString($folder_name . "/" . $row['username'] . '.pdf', $pdf->Output('', 'S'));
+    }
+
+    $zipfile->close();
+
+    header("Content-Type: application/zip");
+    header("Content-Disposition: filename='{$folder_name}.zip'");
+    header('Content-Length: ' . filesize($zipname));
+    readfile($zipname);
+
+    unlink($zipname);
+
+    exit;
 } else {
     $accept_contract = isset($_POST['accept_contract']);
 
diff --git a/modules/mod_view_participants.php b/modules/mod_view_participants.php
index 4f8585e..263f876 100644
--- a/modules/mod_view_participants.php
+++ b/modules/mod_view_participants.php
@@ -130,6 +130,7 @@ $skin->assign(array(
     'participant_list'      => $participant_list,
     'notice_visibility'     => $skin->visibility(count($list) == 0),
     'list_visibility'       => $skin->visibility(count($list) > 0),
+    'archive_url'           => "?q=contract&amp;a=archive&amp;prg={$program_id}",
 ));
 
 // Output the module
diff --git a/skins/easterngreen/html/tpl_view_participants.html 
b/skins/easterngreen/html/tpl_view_participants.html
index 2e7ad21..d814bca 100644
--- a/skins/easterngreen/html/tpl_view_participants.html
+++ b/skins/easterngreen/html/tpl_view_participants.html
@@ -31,4 +31,5 @@
             [[participant_list]]
         </tbody>
     </table>
+    <a href="[[archive_url]]">{{contract_archive}}</a>
 </div>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]