284 lines
10 KiB
PHP
Executable File
284 lines
10 KiB
PHP
Executable File
<?php
|
|
|
|
use PHPMailer\PHPMailer\PHPMailer;
|
|
|
|
require 'thirdparty/PHPMailer/Exception.php';
|
|
|
|
require 'thirdparty/PHPMailer/PHPMailer.php';
|
|
|
|
require 'thirdparty/PHPMailer/SMTP.php';
|
|
|
|
$html = ''; // create empty variable
|
|
$csv = [['Employee number', 'Employee name', 'Date', 'Amount (EUR)', 'Recipient name', 'Activity Tag', 'Activity Text', 'Category ID', 'Category Text', 'Event', 'Description', 'Receipt number']]; // create array for CSV
|
|
$csvfile = tmpfile();
|
|
$csvfile_path = stream_get_meta_data($csvfile)['uri'];
|
|
|
|
$who = isset($_POST['who']) ? $_POST['who'] : false;
|
|
$type = isset($_POST['type']) ? $_POST['type'] : false;
|
|
$rc_month = isset($_POST['rc_month']) ? htmlspecialchars($_POST['rc_month']) : false;
|
|
$rc_year = isset($_POST['rc_year']) ? htmlspecialchars($_POST['rc_year']) : false;
|
|
$cc_month = isset($_POST['cc_month']) ? htmlspecialchars($_POST['cc_month']) : false;
|
|
$cc_year = isset($_POST['cc_year']) ? htmlspecialchars($_POST['cc_year']) : false;
|
|
$entry = isset($_POST['entry']) ? $_POST['entry'] : false; // will become $date in loop
|
|
$amount = isset($_POST['amount']) ? $_POST['amount'] : false;
|
|
$recipient = isset($_POST['recipient']) ? $_POST['recipient'] : false;
|
|
$activity = isset($_POST['activity']) ? $_POST['activity'] : false;
|
|
$category = isset($_POST['category']) ? $_POST['category'] : false;
|
|
$receipt = isset($_POST['receipt']) ? $_POST['receipt'] : false;
|
|
$description = isset($_POST['description']) ? $_POST['description'] : false;
|
|
$event = isset($_POST['event']) ? $_POST['event'] : false;
|
|
$extra = isset($_POST['extra']) ? htmlspecialchars($_POST['extra']) : false;
|
|
$mailopt = isset($_POST['mailopt']) ? $_POST['mailopt'] : false;
|
|
|
|
// create empty arrays for uploaded file
|
|
$receipt_dest = [];
|
|
|
|
// Separate employee name parameters
|
|
$who_verbose = explode('||', $who)[0];
|
|
$who_empnumber = explode('||', $who)[2];
|
|
$who = explode('||', $who)[1];
|
|
|
|
// FUNCTIONS
|
|
function errexit($msg)
|
|
{
|
|
exit('Error: '.$msg.'<br/><br/>To avoid losing your data, press the back button in your browser');
|
|
}
|
|
function replace_page($temp, $content)
|
|
{
|
|
$vars = [':RESULT:' => $content];
|
|
|
|
return str_replace(array_keys($vars), $vars, $temp);
|
|
}
|
|
/* Snippet Begin:
|
|
* SPDX-SnippetLicenseConcluded: CC-BY-SA-4.0
|
|
* SPDX-SnippetCopyrightText: mgutt <https://stackoverflow.com/users/318765/mgutt>
|
|
*/
|
|
function filter_filename($filename, $beautify = true)
|
|
{
|
|
// sanitize filename
|
|
$filename = preg_replace(
|
|
'~
|
|
[<>:"/\\\|?*]| # file system reserved https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
|
|
[\x00-\x1F]| # control characters http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
|
|
[\x7F\xA0\xAD]| # non-printing characters DEL, NO-BREAK SPACE, SOFT HYPHEN
|
|
[#\[\]@!$&\'()+,;=]| # URI reserved https://tools.ietf.org/html/rfc3986#section-2.2
|
|
[{}^\~`] # URL unsafe characters https://www.ietf.org/rfc/rfc1738.txt
|
|
~x',
|
|
'-',
|
|
$filename
|
|
);
|
|
// avoids ".", ".." or ".hiddenFiles"
|
|
$filename = ltrim($filename, '.-');
|
|
// optional beautification
|
|
if ($beautify) {
|
|
$filename = beautify_filename($filename);
|
|
}
|
|
// maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
|
|
$ext = pathinfo($filename, PATHINFO_EXTENSION);
|
|
|
|
return mb_strcut(pathinfo($filename, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($filename)).($ext ? '.'.$ext : '');
|
|
}
|
|
function beautify_filename($filename)
|
|
{
|
|
// reduce consecutive characters
|
|
$filename = preg_replace([
|
|
// "file name.zip" becomes "file-name.zip"
|
|
'/ +/',
|
|
// "file___name.zip" becomes "file-name.zip"
|
|
'/_+/',
|
|
// "file---name.zip" becomes "file-name.zip"
|
|
'/-+/',
|
|
], '-', $filename);
|
|
$filename = preg_replace([
|
|
// "file--.--.-.--name.zip" becomes "file.name.zip"
|
|
'/-*\.-*/',
|
|
// "file...name..zip" becomes "file.name.zip"
|
|
'/\.{2,}/',
|
|
], '.', $filename);
|
|
// lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625
|
|
$filename = mb_strtolower($filename, mb_detect_encoding($filename));
|
|
|
|
// ".file-name.-" becomes "file-name"
|
|
return trim($filename, '.-');
|
|
}
|
|
// Snippet End
|
|
|
|
// Sanity checks for parameters, and setting variables depending on type
|
|
if ('rc' == $type) {
|
|
if (!$rc_month || !$rc_year) {
|
|
errexit('You must provide month and year of the RC');
|
|
}
|
|
$type_verbose = 'Reimbursement Claim';
|
|
$type_date = "{$rc_year}-{$rc_month}";
|
|
} elseif ('cc' == $type) {
|
|
if (!$cc_month || !$cc_year) {
|
|
errexit('You must provide quarter and year of the CC statement');
|
|
}
|
|
$type_verbose = 'Credit Card Statement';
|
|
$type_date = "{$cc_year}-{$cc_month}";
|
|
} else {
|
|
errexit('You must provide a reimbursement type');
|
|
}
|
|
|
|
// Prepare output table
|
|
if ('onlyme' === $mailopt) {
|
|
$html .= '<p><strong>ATTENTION: The email has only been sent to you, not to the financial team!</strong></p>';
|
|
} elseif ('none' === $mailopt) {
|
|
$html .= '<p><strong>ATTENTION: You have configured to not send any email!</strong></p>';
|
|
}
|
|
$html .= "<p>This <strong>{$type_verbose}</strong> is made by <strong>{$who_verbose}</strong>.</p>
|
|
<table class='table table-striped'>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Amount</th>
|
|
<th>Recipient</th>
|
|
<th>Activity Tag</th>
|
|
<th>Activity Text</th>
|
|
<th>Category ID</th>
|
|
<th>Category Text</th>
|
|
<th>Event</th>
|
|
<th>Description</th>
|
|
<th>Receipt Name</th>
|
|
<th></th>
|
|
</tr>";
|
|
|
|
// Prepare email
|
|
$email = new PHPMailer();
|
|
$email->isSMTP();
|
|
$email->Host = 'mail.fsfe.org';
|
|
// Settings on server
|
|
$email->SMTPAuth = false;
|
|
$email->Port = 25;
|
|
// Settings for local debug
|
|
// $email->SMTPAuth = true;
|
|
// $email->Port = 587;
|
|
// $email->Username = 'fsfe_user';
|
|
// $email->Password = 'fsfe_pass';
|
|
// $email->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
|
|
$email->SetFrom($who.'@fsfe.org', $who_verbose);
|
|
$email->CharSet = 'UTF-8';
|
|
$email->Subject = '=?UTF-8?B?'.base64_encode("{$type_verbose} for {$type_date} by {$who_verbose}").'?=';
|
|
if ('normal' === $mailopt) {
|
|
$email->addAddress('finance@lists.fsfe.org');
|
|
}
|
|
$email->addAddress($who.'@fsfe.org');
|
|
|
|
foreach ($entry as $key => $date) { // run over each row
|
|
// Get basic variable for each row
|
|
/* For receipts, following variables are set:
|
|
* tmp: the temporary path of the uploaded file
|
|
* error: any errors with the file
|
|
* name: the original name of the file
|
|
* size: file size
|
|
* rename: the format we want each file to have
|
|
* dest: the temporary but known location of the file
|
|
*/
|
|
$receipt_tmp = $_FILES['receipt']['tmp_name'][$key];
|
|
$receipt_error = $_FILES['receipt']['error'][$key];
|
|
$receipt_name = basename($_FILES['receipt']['name'][$key]);
|
|
$receipt_size = $_FILES['receipt']['size'][$key];
|
|
$key1 = $key + 1;
|
|
$receipt_no = sprintf('%02d', $key1);
|
|
$activity_tag[$key] = explode('||', $activity[$key])[0];
|
|
$activity_text[$key] = explode('||', $activity[$key])[1];
|
|
$category_id[$key] = explode(':', $category[$key])[0];
|
|
$category_text[$key] = explode(':', $category[$key])[1];
|
|
$event[$key] = $event[$key];
|
|
|
|
// Sanity checks for receipt: upload, size, mime type
|
|
if (!$receipt_tmp) {
|
|
errexit("Something with {$receipt_name} went wrong, it has not been uploaded.");
|
|
}
|
|
if ($receipt_size > 2097152) {
|
|
errexit("File size of {$receipt_name} must not be larger than 2MB");
|
|
}
|
|
$receipt_mime = mime_content_type($receipt_tmp);
|
|
if (!in_array($receipt_mime, ['image/jpeg', 'image/png', 'application/pdf'])) {
|
|
errexit("Only PDF, JPG and PNG allowed. {$receipt_name} has {$receipt_mime}");
|
|
}
|
|
|
|
// Set name and temporary destination for attached receipt
|
|
$receipt_ext = pathinfo($receipt_name)['extension'];
|
|
$receipt_rename = filter_filename($type_date.'-'.$type.'-'.$who.'-receipt-'.$receipt_no.'-'.$activity_tag[$key].'.'."{$receipt_ext}");
|
|
$receipt_dest[$key] = '/tmp/'.$receipt_rename;
|
|
|
|
// Try to move file to temporary destination
|
|
if (UPLOAD_ERR_OK == $receipt_error) {
|
|
if (!move_uploaded_file($receipt_tmp, $receipt_dest[$key])) {
|
|
errexit("Could not move uploaded file '".$receipt_tmp."' to '".$receipt_dest."'<br/>\n");
|
|
}
|
|
} else {
|
|
errexit('Upload error. ['.$receipt_error."] on file '".$receipt_name."'<br/>\n");
|
|
}
|
|
|
|
// Remove "-" when remark empty
|
|
if ('-' === $description[$key]) {
|
|
$description[$key] = '';
|
|
}
|
|
|
|
// HTML output for this receipt
|
|
$html .= "
|
|
<tr>
|
|
<td>{$date}</td>
|
|
<td>{$amount[$key]}</td>
|
|
<td>{$recipient[$key]}</td>
|
|
<td>{$activity_tag[$key]}</td>
|
|
<td>{$activity_text[$key]}</td>
|
|
<td>{$category_id[$key]}</td>
|
|
<td>{$category_text[$key]}</td>
|
|
<td>{$event[$key]}</td>
|
|
<td>{$description[$key]}</td>
|
|
<td>{$receipt_name}</td>
|
|
<td></td>
|
|
</tr>";
|
|
|
|
// CSV for this receipt
|
|
$csv[$receipt_no] = [$who_empnumber, $who_verbose, $date, $amount[$key], $recipient[$key], $activity_tag[$key], $activity_text[$key], $category_id[$key], $category_text[$key], $event[$key], $description[$key], $receipt_no];
|
|
|
|
// Add receipt as email attachment
|
|
$email->addAttachment($receipt_dest[$key], basename($receipt_dest[$key]));
|
|
} // foreach
|
|
|
|
// Write and attach temporary CSV file
|
|
foreach ($csv as $fields) {
|
|
fputcsv($csvfile, $fields, ';', '"', '"');
|
|
}
|
|
$email->addAttachment($csvfile_path, filter_filename($type_date.'-'.$type.'-'.$who.'.csv'));
|
|
|
|
// Prepare email body
|
|
$email_body = "Hi,
|
|
|
|
This is a {$type_verbose} for {$type_date} by {$who_verbose},
|
|
sent via <https://fsfe.org/internal/rc>.
|
|
|
|
Please find the expenses and their receipts attached.";
|
|
|
|
// Finalise output table
|
|
$html .= '</table>';
|
|
if ($extra) {
|
|
$html .= "<p>Extra remarks: <br />{$extra}</p>";
|
|
|
|
$email_body .= "
|
|
|
|
The sender added the following comment:
|
|
|
|
{$extra}";
|
|
}
|
|
|
|
// Send email, and delete attachments
|
|
$email->Body = $email_body;
|
|
if ('normal' === $mailopt || 'onlyme' === $mailopt) {
|
|
$email->send();
|
|
$html .= $email->ErrorInfo;
|
|
}
|
|
foreach ($receipt_dest as $receipt) {
|
|
unlink($receipt);
|
|
}
|
|
fclose($csvfile);
|
|
|
|
// --- PRINT OUTPUT IN TEMPLATE FILE ---
|
|
|
|
$template = file_get_contents('../internal/rc-result.en.html', true);
|
|
|
|
echo replace_page($template, $html);
|