You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

278 lines
10 KiB
PHP

<?php
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
require_once __DIR__ . "/../../lib/requiredpublic.php";
require_once __DIR__ . "/../../lib/Email.lib.php";
function errorBack(string $errormsg) {
global $familyid;
//header("Location: ../?page=signup&error=" . htmlentities($errormsg));
$database->delete("families", ["familyid" => $familyid]);
die($errormsg);
}
if (!empty($SETTINGS["disable_registration"]) && $SETTINGS["disable_registration"] == true) {
die("Online registration is now closed.");
}
$database->action(function($database) {
global $SETTINGS;
$database->insert("families", []);
$familyid = $database->id();
$dueusd = 0.0;
$emails = [];
try {
$people = $_POST['people'];
$requiredfields = [
"firstname" => ".+",
"lastname" => ".+",
"address" => ".+",
"zip" => "[0-9]{5}(-?[0-9]{4})?",
"phone1" => "[0-9]{10}",
"email" => "_EMAIL_",
"shirt" => ["NO", "YS", "YM", "YL", "AS", "AM", "AL", "AX", "A2", "A3"],
"sex" => ["M", "F"]
];
if (count($people['ids']) == 0) {
errorBack("You need to register at least one person.");
}
$campercount = 0;
foreach ($people['ids'] as $pid) {
if ($people["type"][$pidd] == "camper") {
$campercount++;
}
}
foreach ($people['ids'] as $pid) {
// Clear these out
$camperid = null;
$adultid = null;
$youthid = null;
switch ($people["type"][$pid]) {
case "camper":
$checkfields = array_merge($requiredfields, [
"parentname" => ".+",
"unit" => "[0-9]{3,4}",
"rank" => ["Tiger", "Wolf", "Bear", "Webelos", "Arrow of Light"]
]);
break;
case "adult":
$checkfields = array_merge($requiredfields, [
"position" => [
"None",
"Den Walker",
"Station Leader",
"Tot Lot",
"First Aid",
"Floater"
]
]);
break;
case "youth":
$checkfields = array_merge($requiredfields, [
"position" => [
"None",
"Den Chief",
"Station",
"Tot Lot",
"Floater"
]
]);
break;
default:
errorBack("Invalid person type.");
}
foreach ($checkfields as $name => $regex) {
$validatefunction = function ($str) use ($regex) {
return preg_match("/$regex/", $str);
};
if (is_array($regex)) {
// Array of options
$validatefunction = function ($str) use ($regex) {
return in_array($str, $regex);
};
} else if (strpos($regex, "_") === 0) {
// Special cases
switch ($regex) {
case "_EMAIL_":
$validatefunction = function ($str) {
return filter_var($str, FILTER_VALIDATE_EMAIL);
};
break;
}
}
// Validate
if (!$validatefunction($people[$name][$pid])) {
errorBack("Please check your input and try again ($name).");
}
}
$days = "";
if (is_array($people["days"][$pid])) {
foreach ($SETTINGS["camp_days"] as $short => $long) {
$validdays[] = $short;
}
$days = "";
foreach ($people["days"][$pid] as $day) {
if (in_array($day, $validdays)) {
$days .= $day;
}
}
}
switch ($people["type"][$pid]) {
case "camper":
$dueusd += 50.0;
echo "\nAdding $50 to the total for a camper, dueusd is $dueusd\n";
$database->insert("campers", [
"parentname" => $people["parentname"][$pid],
"rank" => $people["rank"][$pid]
]);
$camperid = $database->id();
break;
case "adult":
$discount = 10.0 * (strlen($days) / 2);
$dueusd -= $discount;
echo "Subtracting $$discount from the total for an adult volunteer, dueusd is $dueusd\n";
// Add shirt charge if not working all days
if ($SETTINGS["prices"]["alone_adult_free_tshirt"] === true && $campercount == 0) {
// No shirt cost
} else if ($SETTINGS["prices"]["adult_tshirt"] !== false) {
if ($people["shirt"][$pid] != "NO" && (strlen($days) / 2) < $SETTINGS["prices"]["adult_tshirt"]) {
echo "Adding $10 for a tshirt.\n";
$dueusd += 10.0;
}
}
$database->insert("adults", [
"position" => $people["position"][$pid],
"days" => $days,
"child_care" => (empty($people["child_care"][$pid]) ? null : $people["child_care"][$pid])
]);
$adultid = $database->id();
break;
case "youth":
if ($SETTINGS["prices"]["youth_tshirt"] !== false) {
if ($people["shirt"][$pid] != "NO" && (strlen($days) / 2) < $SETTINGS["prices"]["youth_tshirt"]) {
echo "Adding $10 for a tshirt.\n";
$dueusd += 10.0;
}
}
$database->insert("youth", [
"position" => $people["position"][$pid],
"days" => $days
]);
$youthid = $database->id();
break;
}
$database->insert("people", [
"familyid" => $familyid,
"camperid" => $camperid,
"adultid" => $adultid,
"youthid" => $youthid,
"firstname" => $people["firstname"][$pid],
"lastname" => $people["lastname"][$pid],
"address" => $people["address"][$pid],
"zip" => $people["zip"][$pid],
"phone1" => empty($people["phone1"][$pid]) ? "" : $people["phone1"][$pid],
"phone2" => empty($people["phone2"][$pid]) ? "" : $people["phone2"][$pid],
"email" => empty($people["email"][$pid]) ? "" : $people["email"][$pid],
"unit" => $people["unit"][$pid],
"shirt" => $people["shirt"][$pid],
"sex" => $people["sex"][$pid]
]);
if (!empty($people["email"][$pid])) {
$emails[] = $people["email"][$pid];
}
}
} catch (Exception $ex) {
errorBack($ex->getMessage());
}
//
// Payment
//
$campcoupons = (!empty($_POST['campcoupons']) && preg_match("/[0-9]+/", $_POST['campcoupons'])) ? $_POST['campcoupons'] * 1 : 0;
if ($campcoupons < 0) {
$campcoupons = 0;
}
$dueusd = max(0, $dueusd);
$duecard = max(0, $dueusd - $campcoupons);
echo "\nCost $dueusd total: $duecard to Stripe, $campcoupons as coupons\n";
if ($dueusd != $_POST['totalcharge']) {
errorBack("There was a discrepency between the total you saw and the total the server calculated. The transaction has been cancelled and you were not charged.");
}
if ($duecard > 0) {
try {
\Stripe\Stripe::setApiKey($SETTINGS["stripe"]["seckey"]);
$chargedata = [
'amount' => $duecard * 100.0,
'currency' => 'usd',
'description' => 'Day Camp ' . date('Y'),
'source' => $_POST['stripeToken']
];
if (count($emails) > 0) {
$chargedata['receipt_email'] = $emails[0];
}
$charge = \Stripe\Charge::create($chargedata);
} catch (\Stripe\Error\Card $e) {
$body = $e->getJsonBody();
$err = $body['error'];
errorBack("We couldn't process your card because it was declined. Your card issuer or bank sent us this message: " . $err["message"] . " That's all we know.");
} catch (\Stripe\Error\RateLimit $e) {
errorBack("We couldn't process your card because things are happening too fast. Please try again in a minute. Your card was not charged. (Error code: STRIPE_RATELIMIT)");
} catch (\Stripe\Error\InvalidRequest $e) {
errorBack("We couldn't process your card because of a technical issue. Please try again later. Your card was not charged. (Error code: STRIPE_INVREQ)");
} catch (\Stripe\Error\Authentication $e) {
errorBack("We can't connect to the card processor. Please try again later. Your card was not charged. (Error code: STRIPE_AUTH)");
} catch (\Stripe\Error\ApiConnection $e) {
errorBack("We can't connect to the card processor. Please try again later. Your card was not charged. (Error code: STRIPE_NOAPI)");
} catch (\Stripe\Error\Base $e) {
errorBack("An unknown payment error occurred. Please try again later. Your card was not charged.");
} catch (Exception $e) {
errorBack("An unknown error occurred. Please try again later. Your card was not charged.");
}
}
$database->insert("payments", [
"familyid" => $familyid,
"amount" => $dueusd,
"amountpaid" => $duecard,
"date" => date("Y-m-d H:i:s"),
"type" => "Online"
]);
header("Location: ../?page=thanks");
return true;
});