[opw-web] Add the functionality to get an archive of signed contracts for a program
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [opw-web] Add the functionality to get an archive of signed contracts for a program
- Date: Sun, 14 Jun 2015 17:56:38 +0000 (UTC)
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&a=archive&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]