Last active
March 10, 2016 02:30
-
-
Save alexweissman/1221158aac8c8db9a1a9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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"); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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