Skip to content

Instantly share code, notes, and snippets.

@alexweissman
Last active March 10, 2016 02:30
Show Gist options
  • Select an option

  • Save alexweissman/1221158aac8c8db9a1a9 to your computer and use it in GitHub Desktop.

Select an option

Save alexweissman/1221158aac8c8db9a1a9 to your computer and use it in GitHub Desktop.
<?php
namespace UserFrosting;
use \Illuminate\Database\Capsule\Manager as Capsule;
/**
* CustomerRequest Class
*
* Represents a customer request from a frontend website.
*
* @author Alex Weissman
*
* @property string first_name
* @property string last_name
* @property string email
* @property string phone
* @property int package_id
* @property string major
* @property int intake_id
* @property string followup_response
* @property string payment_method
* @property string availability
* @property string comments
* @property string promo
* @property datetime request_time
* @property bool routed
*/
class CustomerRequest extends UFModel {
/**
* @var string The id of the table for the current model.
*/
protected static $_table_id = "customer_request";
/**
* Create a new CustomerRequest object.
*
*/
public function __construct($properties = []) {
parent::__construct($properties);
}
/**
* Get the session package associated with this request.
*/
public function package() {
return $this->belongsTo('UserFrosting\SessionPackage', 'package_id');
}
/**
* Get the intake method associated with this request.
*/
public function intake_method() {
return $this->belongsTo('UserFrosting\IntakeMethod', 'intake_id');
}
/**
* Get the courses (that already exist in our system) that were submitted with this request.
*/
public function courses() {
return $this->belongsToMany("UserFrosting\Course", "web_request_courses", "request_id")->withPivot("instructor", "description")->whereRaw("course_id IS NOT NULL");
}
/**
* Get the courses (that are not yet verified in our system) that were submitted with this request.
*/
public function courses_new() {
return $this->hasMany("UserFrosting\CustomerRequestCourse", "request_id")->whereRaw("course_id IS NULL")->orWhere("course_id", "0");
}
}
<?php
/**
* Process a request submission.
*
* This resource is publicly accessible.
* Request type: POST
*/
public static function createCustomerRequest(){
$app = UserFrosting::getInstance();
$twig = $app->view()->getEnvironment();
$coordinator = $app->config('contacts')['coordinator'];
// POST: first_name, last_name, email, phone, courses, package_id, major, intake_id, followup_response, payment_method, availability, comments, promo, spiderbro
$post = $app->request->post();
// Get the alert message stream
$ms = $app->alerts;
//$ms->resetMessageStream();
// Check the honeypot. 'spiderbro' is not a real field, it is hidden on the main page and must be submitted with its default value for this to be processed.
if (!isset($post['spiderbro']) || $post['spiderbro'] != "http://"){
error_log("Possible spam received:" . print_r($app->request->post(), true));
$ms->addMessage("danger", "Aww hellllls no!");
$app->halt(500); // Don't let on about why the request failed ;-)
}
// Load the request schema
$schema = $app->loadRequestSchema('/request.json');
// Set up Fortress to process the request
$rf = new \Fortress\HTTPRequestFortress($ms, $schema, $post);
// Sanitize data
$rf->sanitize();
// Validate, and halt on validation errors.
if (!$rf->validate()) {
$app->halt(400);
}
// Get the filtered data
$data = $rf->data();
// Creating the new request and pinging the Stripe API must either both succeed or both fail.
// Thus, we use a transaction.
$DB = Capsule::connection();
$request = Capsule::transaction( function() use ($app, $twig, $data, $coordinator) {
// Get info for each course
$courses = $data['courses'];
// Remove from $data for db insertion
unset($data['courses']);
$stripe_token = $data['stripe_token'];
unset($data['stripe_token']);
$request = new CustomerRequest($data);
$request->save();
// Create request course objects. For course_ids that exist in the table, we simply attach them. Otherwise, we create a "dangling" request course.
foreach($courses as $course){
// If the course exists in the DB, attach it to this request
$backend_course = Course::find($course['course_id']);
if ($backend_course) {
$request->courses()->attach($course['course_id'], [
"instructor" => $course['instructor']
]);
} else {
// Otherwise, add a dangling record
$request_course = new CustomerRequestCourse([
"request_id" => $request->id,
"instructor" => $course['instructor'],
"description" => $course['course_id']
]);
$request_course->save();
}
}
// If Stripe token is present, create a new Stripe customer
if ($stripe_token){
// Setup Stripe
\Stripe\Stripe::setApiKey($app->config('stripe')['secret']);
try {
// Create a Customer
$customer = \Stripe\Customer::create([
"source" => $stripe_token,
"email" => $data['email'],
"metadata" => [
"request_id" => $request->id,
"name" => $data['first_name'] . " " . $data['last_name'],
"package" => "{$request->package->package_name} - {$request->package->sessions} session(s) - \${$request->package->price}",
"phone" => $data['phone'],
"promo" => $data['promo']
]
]);
} catch(\Stripe\Error\Card $e) {
$body = $e->getJsonBody();
$err = $body['error'];
$message_template = $twig->loadTemplate('messages/error-stripe.twig');
$message = $message_template->render([
'message' => $err['message'],
'phone' => $coordinator['phone']
]);
$app->alerts->addMessage("danger", $message);
// Roll back any changes
$app->halt(402);
} catch (Exception $e) {
$app->alerts->addMessage("warning", "We were unable to authorize your card. You may try again with a different credit card, or simply pay in person.");
}
// TODO: Associate with request
}
// If we've made it this far, commit the DB transaction!
return $request;
});
// TODO: Create Student and Request objects, link with Stripe info
$request->load('courses');
$request->load('courses_new');
$request->load('intake_method');
$request->load('package');
// Send request alert to local tutor coordinator
// For now, coordinator info is hard-coded into config file. Eventually we should pull it from a DB
$template = $twig->loadTemplate("mail/new-request.twig");
$notification = new \UserFrosting\Notification($template);
$notification->from(
$coordinator['email'],
$coordinator['name'],
$request->email,
$request->first_name . ' ' . $request->last_name
);
$notification->addEmailRecipient(
$coordinator['email'],
$coordinator['name'], [
"request" => $request
]
);
try {
$notification->send();
} catch (\phpmailerException $e){
$app->alerts->addMessage("warning", "Your request was received, but we're having trouble with our mail servers at the moment. If you don't hear from us in 8 hours, please submit another request.");
error_log('Mailer Error: ' . $e->errorMessage());
$app->halt(500);
}
// Send confirmation email to student
$template = $twig->loadTemplate("mail/student-confirm-request.twig");
$notification = new \UserFrosting\Notification($template);
$notification->from(
$coordinator['email'],
$coordinator['name'],
$coordinator['reply_email'],
$coordinator['reply_name']
);
$notification->addEmailRecipient(
$request->email,
$request->first_name . ' ' . $request->last_name, [
"request" => $request
]
);
try {
$notification->send();
} catch (\phpmailerException $e){
$app->alerts->addMessage("warning", "Your request was received, but we're having trouble with our mail servers at the moment. If you don't hear from us in 8 hours, please submit another request.");
error_log('Mailer Error: ' . $e->errorMessage());
$app->halt(500);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment