src/Controller/RCS/AuthController.php line 150

  1. <?php
  2. namespace App\Controller\RCS;
  3. use Symfony\Component\Routing\Annotation\Route;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\HttpFoundation\Response;
  6. use Symfony\Component\HttpFoundation\RedirectResponse;
  7. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  8. use App\Entity\Purchase;
  9. use App\Entity\PurchaseItem;
  10. use App\Entity\User;
  11. use App\Entity\Contact;
  12. use App\Entity\Coupon;
  13. use App\Entity\PurchaseNote;
  14. use App\Entity\Product;
  15. use App\Utils\ContentHelper;
  16. use App\Utils\UserHelper;
  17. use App\Utils\ContactHelper;
  18. use App\Utils\EmailHelper;
  19. use App\Utils\OrderHelper;
  20. use App\Utils\LeadHelper;
  21. use App\Security\WordPressPasswordEncoder;
  22. use App\Exception\ResourceNotFoundException;
  23. //use Symfony\Bridge\Doctrine\Security\RememberMe\DoctrineTokenProvider;
  24. use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
  25. use Symfony\Component\HttpFoundation\Cookie;
  26. //todo: Make a Master AuthController, and combine any other controllers that we can
  27. class AuthController extends DefaultController
  28. {
  29.     /**
  30.      * @Route("/sign-in",
  31.      *    name="sign-in-post",
  32.      *    defaults={"message": ""},
  33.      *  methods={"POST"}
  34.      *    )
  35.      */
  36.     public function signInPost(
  37.         Request $request,
  38.         UserHelper $userHelper,
  39.         EmailHelper $emailHelper,
  40.         //DoctrineTokenProvider $doctrineTokenProvider,
  41.         $message ""
  42.     
  43.     {
  44.         $username $request->get("_username");
  45.         $password $request->get("_password");
  46.         if(!$emailHelper->checkCaptcha($request->get("g-recaptcha-response"))) {
  47.             //$this->addFlash("warning", "The reCAPTCHA was invalid. Please try again.");
  48.             $message = array (
  49.                 "type" => "warning",
  50.                 "text" => "The reCAPTCHA was invalid. Please try again.",
  51.             );
  52.             return $this->defaultRender("forms/sign-in.html.twig", [
  53.                 "message" => $message,
  54.             ]);
  55.         }
  56.         $session $request->getSession();
  57.         $nRoute $session->get("non_sign_in_route");
  58.         $path = !empty($nRoute["path"]) ? $nRoute["path"] : "/";
  59.         $result $userHelper->signIn(
  60.             $username
  61.             $password
  62.         );
  63.         if(is_array($result) && $result["status"] == 2) {
  64.             return new RedirectResponse("/mfa/{$result['uid']}/{$result['token']}");
  65.         }
  66.         elseif (is_array($result) && $result["status"] == 1) {
  67.             $this->addFlash("success""You have successfully logged in.");
  68.             $response = new RedirectResponse($path);
  69.             //$response = $this->setRememberMe($request, $response, $doctrineTokenProvider, $username);
  70.         }
  71.         else {
  72.             $message = array (
  73.                 "type" => "warning",
  74.                 "text" => "Invalid credentials provided.",
  75.             );
  76.             return $this->defaultRender("forms/sign-in.html.twig", [
  77.                 "message" => $message,
  78.             ]);
  79.         }
  80.         
  81.         return $response;
  82.     }
  83.     
  84.     /**
  85.      * @Route("/sign-in",
  86.      *    name="sign-in",
  87.      *    defaults={"message": ""}
  88.      *    )
  89.      */
  90.     public function signIn(
  91.         Request $request,
  92.         AuthenticationUtils $authUtils,
  93.         WordPressPasswordEncoder $wpEncoder,
  94.         $message ""
  95.     ) {
  96.         //just testing: $message = $wpEncoder->hash("M0byd1ck771!"); 
  97.         //$message = null;
  98.         $message $request->query->get("message") ?? "";
  99.         
  100.         $error $authUtils->getLastAuthenticationError();
  101.         $lastUsername $authUtils->getLastUsername();
  102.         if ($error) {
  103.             $message = array (
  104.                 "type" => "warning",
  105.                 "text" => "Invalid credentials.",
  106.             );
  107.         }
  108.         
  109.         
  110.         return $this->defaultRender("forms/sign-in.html.twig", [
  111.             "last_username" => $lastUsername,
  112.             // "error" => $error,
  113.             "message" => $message,
  114.         ]);
  115.     }
  116.     
  117.     /**
  118.      * @Route("/forgot-password", name="forgot-password")
  119.      */
  120.     public function forgotPassword (
  121.         Request $request,
  122.         UserHelper $userHelper,
  123.         ContactHelper $contactHelper,
  124.         EmailHelper $emailHelper
  125.     ) {        
  126.         // should we rate limit ??
  127.         $username $request->request->get("username");
  128.         $message = array ();
  129.         
  130.         if ($username) {
  131.             $rsp $userHelper->forgotPassword($username);
  132.             $message = array(
  133.                 "type" => $rsp["status"] ? "success" "warning",
  134.                 "text" => $rsp["message"],
  135.             );
  136.         }
  137.         
  138.         return $this->defaultRender("forms/forgot-password.html.twig", [
  139.             "message" => $message,
  140.         ]);
  141.     }
  142.     
  143.     /**
  144.      * @Route("/forgot-username", name="forgot-username", methods={"POST"})
  145.      */
  146.     public function forgotUsername (
  147.         Request $request,
  148.         UserHelper $userHelper
  149.     ) {
  150.         $email $request->get("email");
  151.         $rsp $userHelper->forgotUsername($email);
  152.         $msg = array ();
  153.         
  154.         if ($rsp["status"]) {
  155.             $msg = array (
  156.                 "type" => "success",
  157.                 "text" => $rsp["message"],
  158.             );
  159.         } 
  160.         
  161.         else {
  162.             sleep (3);
  163.             $msg = array (
  164.                 "type" => "warning",
  165.                 "text" => $rsp["message"],
  166.             );
  167.         }
  168.         
  169.         return $this->defaultRender("forms/forgot-username.html.twig", [
  170.             "message" => $msg
  171.         ]);
  172.         
  173.         /*
  174.         try {
  175.             $user = $userHelper->getUserByEmail($email);
  176.             $username = $user->getUsername();
  177.             
  178.             return $this->defaultRender("forms/sign-in.html.twig", [
  179.                 "message" => [
  180.                     "type" => "success",
  181.                     "text" => "The username linked to that account is <strong>{$username}</strong>.",
  182.                 ]
  183.             ]);
  184.             
  185.         } catch (ResourceNotFoundException $e) {
  186.             sleep(3);
  187.             return $this->defaultRender("forms/forgot-username.html.twig", [
  188.                 "message" => [
  189.                     "type" => "warning",
  190.                     "text" => "That e-mail address was not found in the system.",
  191.                 ]
  192.             ]);
  193.         } 
  194.         */    
  195.     }
  196.     
  197.     /**
  198.      * @Route("/forgot-username", name="forgot-username-form")
  199.      */
  200.     public function viewForgotUsername (
  201.     
  202.     ) {
  203.         
  204.         return $this->defaultRender("forms/forgot-username.html.twig", [
  205.             "message" => array ()
  206.         ]);
  207.     }
  208.     
  209.     /**
  210.      * @Route("/rcs-reset-password/{id}/{token}", name="reset-password-form", defaults={"message": ""})
  211.      */
  212.     public function viewResetPassword (
  213.         UserHelper $userHelper,
  214.         Request $request,
  215.         $id
  216.         $token,
  217.         $message ""
  218.     ) {
  219.         
  220.         try {
  221.             $user $userHelper->getUserById($id);
  222.             
  223.             $message $request->query->get("message") ?? "";
  224.             // if token does not match 
  225.             if ($token != $user->getResetPwToken()) {
  226.                 return $this->defaultRender("errors/404.html.twig");
  227.             }
  228.             
  229.             return $this->defaultRender("forms/reset-password.html.twig", [
  230.                 "user" => $user,
  231.                 "id" => $id,
  232.                 "token" => $token,
  233.                 "message" => $message
  234.             ]);
  235.         } catch (ResourceNotFoundException $e) {
  236.             
  237.         }
  238.     }
  239.     
  240.     /**
  241.      * @Route("/rcs-reset-password", name="reset-password", methods={"POST"})
  242.      */
  243.     public function resetPassword (
  244.         Request $request,
  245.         WordPressPasswordEncoder $wpEncoder,
  246.         UserHelper $userHelper
  247.     ) {
  248.         
  249.         $id $request->get("id");
  250.         $token $request->get("token");
  251.         $password1 $request->get("password1");
  252.         $password2 $request->get("password2");
  253.         
  254.         $rsp $userHelper->resetPassword(
  255.             $id,
  256.             $token,
  257.             $password1,
  258.             $password2
  259.         );
  260.         
  261.         $msg = array ();
  262.         
  263.         if ($rsp["status"]) {
  264.             $msg = array (
  265.                 "type" => "success",
  266.                 "text" => $rsp["message"],
  267.             );
  268.             return $this->redirectToRoute("sign-in", [
  269.                 "message" => $msg
  270.             ]);
  271.         } 
  272.         
  273.         else {
  274.             $msg = array (
  275.                 "type" => "warning",
  276.                 "text" => $rsp["message"],
  277.             );
  278.             return $this->redirectToRoute("reset-password-form", [
  279.                "id" => $id,
  280.                "token" => $token,
  281.                "message" => $msg
  282.             ]);
  283.         }
  284.         
  285.     }
  286.      
  287.     /* *
  288.      * @ R o u t e ("/rcs-sign-up", name="sign-up", methods={"POST"})
  289.      * /
  290.     public function signUp (
  291.         Request $request,
  292.         UserHelper $userHelper,
  293.         EmailHelper $emailHelper
  294.     ) {
  295.         
  296.         $username = $request->get("username");
  297.         $email = $request->get("email");
  298.         
  299.         if($emailHelper->checkCaptcha($request->get("g-recaptcha-response"))) {
  300.             
  301.             $password1 = $request->get("password1");
  302.             $password2 = $request->get("password2");
  303.             
  304.             $rsp = $userHelper->signUp(
  305.                 $username,
  306.                 $email,
  307.                 $password1,
  308.                 $password2
  309.             );
  310.             
  311.             if ($rsp["status"]) {
  312.                 return $this->defaultRender("forms/sign-in.html.twig", [
  313.                     "message" => $rsp["message"],
  314.                 ]);
  315.             }
  316.             
  317.             return $this->defaultRender("forms/sign-up.html.twig", [
  318.                 "username" => $username,
  319.                 "email" => $email,
  320.                 "message" => $rsp["message"],
  321.             ]);
  322.         }
  323.         else {
  324.             return $this->defaultRender("forms/sign-up.html.twig", [
  325.                 "username" => $username,
  326.                 "email" => $email,
  327.                 "message" => [
  328.                     "type" => "warning",
  329.                     "text" => "The reCAPTCHA was invalid. Please try again.",
  330.                 ],
  331.             ]);
  332.         }
  333.     }
  334.     */
  335.     
  336.     /* *
  337.      * @ R o u t e("/rcs-sign-up", name="sign-up-form")
  338.      * /
  339.     public function viewSignUp (
  340.     
  341.     ) {
  342.         
  343.         return $this->defaultRender("forms/sign-up.html.twig", [
  344.             "username" => "",
  345.             "email" => "",
  346.             "message" => array (
  347.             
  348.             )
  349.         ]);
  350.     }
  351.     */
  352.     
  353.     /**
  354.      * @Route("/sign-up", name="new-sign-up", methods={"POST"})
  355.      */
  356.     public function newSignUp (
  357.         Request $request,
  358.         UserHelper $userHelper,
  359.         EmailHelper $emailHelper,
  360.         LeadHelper $leadHelper,
  361.         ContentHelper $contentHelper
  362.     ) {
  363.         //Switching from reCaptcha to Cloudflare turnstile
  364.         $secret "0x4AAAAAAAi4CA7s2RKmrc-uH218wVf8Bcs";
  365.         //$secret = "0x4AAAAAAAi4CA7s2RKmrc-uH218wVf8bct"; //bad
  366.         $remote_addr $_SERVER['REMOTE_ADDR'];
  367.         $cf_url 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
  368.         //$token = $_POST['cf-turnstile-response'];
  369.         $token $request->get("cf-turnstile-response");
  370.         
  371.         $cfVerified false;
  372.          // Request data
  373.          $data = array(
  374.             "secret" => $secret,
  375.             "response" => $token,
  376.             "remoteip" => $remote_addr
  377.         );
  378.         // Initialize cURL
  379.         $curl curl_init();
  380.          // Set the cURL options
  381.          curl_setopt($curlCURLOPT_URL$cf_url);
  382.          curl_setopt($curlCURLOPT_POSTtrue);
  383.          curl_setopt($curlCURLOPT_POSTFIELDS$data);
  384.          curl_setopt($curlCURLOPT_RETURNTRANSFERtrue);
  385.          // Execute the cURL request
  386.          $response curl_exec($curl);
  387.           // Check for errors
  388.         if (curl_errno($curl)) {
  389.             $error_message curl_error($curl);
  390.             // Handle the error the way you like it
  391.             //echo 'cURL Error: ' . $error_message.'<br>';
  392.         }else{
  393.                 /* Parse Cloudflare's response and check if there are any validation errors */
  394.                 $response json_decode($response,true);
  395.                 if ($response['error-codes'] && count($response['error-codes']) > 0){
  396.                     /*
  397.                     echo 'Cloudflare Turnstile check failed. Error codes:<br>';
  398.                     echo '<ul>';
  399.                     foreach($response['error-codes'] as $e){
  400.                         echo '<li>'.$e.'</li>';
  401.                     }
  402.                     echo '</ul>';
  403.                     echo '<br><br>Output from Cloudflare:<br><br>';
  404.                     print_r($response);
  405.                     */
  406.                 }else{
  407.                     $cfVerified true;
  408.                     /*
  409.                     echo 'Passed Cloudflare Turnstile check.<br><br>Output from Cloudflare:<br><br>';
  410.                     print_r($response);
  411.                     echo '<hr>';
  412.                     // Process the response
  413.                     //echo 'The submitted form data is : '.$_POST['field1'];
  414.                     */
  415.                 }
  416.         }
  417.             // Close cURL
  418.             curl_close($curl);
  419.         $honeypot $request->get("timer1"); //this is a honeypot field
  420.         $timer $request->get("timer2");
  421.         if($honeypot != "" || $timer == "" || !is_numeric($timer) || (int)$timer 11 ) {
  422.             $cfVerified false;
  423.         }
  424.         //if(!$emailHelper->checkCaptcha($request->get("g-recaptcha-response"))) {
  425.         if(!$cfVerified) {
  426.             
  427.             $lead $request->get("lead");
  428.             
  429.             $firstname array_key_exists("firstname"$lead) ? $lead["firstname"] : "";
  430.             $lastname array_key_exists("lastname"$lead) ? $lead["lastname"] : "";
  431.             $email array_key_exists("email"$lead) ? $lead["email"] : "";
  432.             $username array_key_exists("username"$lead) ? $lead["username"] : "";
  433.             $address1 array_key_exists("address1"$lead) ? $lead["address1"] : "";
  434.             $address2 array_key_exists("address2"$lead) ? $lead["address2"] : "";
  435.             $city array_key_exists("city"$lead) ? $lead["city"] : "";
  436.             $state array_key_exists("state"$lead) ? $lead["state"] : "";
  437.             $zip array_key_exists("zip"$lead) ? $lead["zip"] : "";
  438.             $company array_key_exists("company"$lead) ? $lead["company"] : "";
  439.             $phone array_key_exists("phone"$lead) ? $lead["phone"] : "";
  440.             
  441.             //$this->addFlash("warning", "The reCAPTCHA was invalid. Please try again.");
  442.             return $this->defaultRender("forms/new-sign-up.html.twig", [
  443.                 "username" => $username,
  444.                 "email" => $email,
  445.                 "firstname" => $firstname,
  446.                 "lastname" => $lastname,
  447.                 "address1" => $address1,
  448.                 "address2" => $address2,
  449.                 "city" => $city,
  450.                 "state" => $state,
  451.                 "zip" => $zip,
  452.                 "company" => $company,
  453.                 "phone" => $phone,
  454.                 "message" => [
  455.                     "type" => "warning",
  456.                     "text" => "The reCAPTCHA was invalid. Please try again.",
  457.                 ]
  458.             ]);
  459.         }
  460.         
  461.         
  462.         $siteSignup $request->get("site-signup");
  463.         $enewsSignup $request->get("enews-signup");
  464.         //$enewsMetalSignup = $request->get("enews-metal-signup");
  465.         
  466.         $enewsSignupSuccess false//store if they signed up for the enews
  467.         $enewsMetalSignupSuccess false//store if they signed up for metal enews
  468.         $siteSignupSuccess false//store if they signed up for the site
  469.         
  470.         
  471.         if($siteSignup) {
  472.             //Handle the form for signing up to the site.
  473.             $lead $request->get("lead");
  474.             
  475.             $username $lead["username"];
  476.             $email $lead["email"];
  477.             $email trim($email);
  478.             $firstname $lead["firstname"];
  479.             $lastname $lead["lastname"];
  480.             
  481.             $address1 $lead["address1"];
  482.             $address2 $lead["address2"];
  483.             $city $lead["city"];
  484.             $state $lead["state"];
  485.             $zip $lead["zip"];
  486.             $company $lead["company"];
  487.             $phone $lead["phone"];
  488.             
  489.             $password1 $request->get("password1");
  490.             $password2 $request->get("password2");
  491.             
  492.             $rsp $userHelper->signUp(
  493.                 $firstname,
  494.                 $lastname,
  495.                 $username,
  496.                 $email,
  497.                 $password1,
  498.                 $password2
  499.             );
  500.             
  501.             if ($rsp["status"]) { //success
  502.                 $siteSignupSuccess true;
  503.                 //return new RedirectResponse('/welcome-activation');
  504.             }
  505.             else {
  506.                 
  507.                 //$this->addFlash("warning", $rsp["message"]);
  508.                 return $this->defaultRender("forms/new-sign-up.html.twig", [
  509.                     "username" => $username,
  510.                     "email" => $email,
  511.                     "firstname" => $firstname,
  512.                     "lastname" => $lastname,
  513.                     "address1" => $address1,
  514.                     "address2" => $address2,
  515.                     "city" => $city,
  516.                     "state" => $state,
  517.                     "zip" => $zip,
  518.                     "company" => $company,
  519.                     "phone" => $phone,
  520.                     "message" => $rsp["message"],
  521.                 ]);
  522.                 
  523.             }
  524.             
  525.         }
  526.         
  527.         
  528.         
  529.         if ($enewsSignup || ($siteSignup && $siteSignupSuccess && ($request->get("enews") || $request->get("metal-enews") || $request->get("coatings-enews")))) {
  530.             //Handle the form for signing up for just enews-signup
  531.             $lead $request->get("lead");
  532.             
  533.             $firstname $lead["firstname"];
  534.             $lastname $lead["lastname"];
  535.             $email $lead["email"];
  536.             $email trim($email);
  537.             $company $lead["company"];
  538.             $contractor_type $lead["contractor_type"];
  539.             $country = ($lead["country"] == "Other" $lead["country_other"] : $lead["country"]);
  540.             $business_type $lead["business_type"];
  541.             
  542.             if(empty($email) || filter_var($emailFILTER_VALIDATE_EMAIL) === false){
  543.                 $this->addFlash("warning""Please enter a valid email address.");
  544.                 return new RedirectResponse($request->headers->get('referer'));
  545.             }            
  546.             if(empty($firstname)){
  547.                 $this->addFlash("warning""Please enter your first name");
  548.                 return new RedirectResponse($request->headers->get('referer'));
  549.             }
  550.             if(empty($lastname)){
  551.                 $this->addFlash("warning""Please enter your last name");
  552.                 return new RedirectResponse($request->headers->get('referer'));
  553.             }
  554.             if(empty($company)){
  555.                 $this->addFlash("warning""Please enter your company");
  556.                 return new RedirectResponse($request->headers->get('referer'));
  557.             }
  558.             
  559.             try {
  560.                 //add to mailchimp list
  561.                 
  562.                 // MailChimp API credentials
  563.                 $apiKey "27ce559264a47aa3487224e1c95424bc-us10";
  564.                 $listID "3efdbc4139";
  565.                 
  566.                 // Determine wir wim or both
  567.                 $keys = [];
  568.                 if ($request->get("enews")) {
  569.                     array_push($keys'WIR');
  570.                 }
  571.                 if ($request->get("metal-enews")) {
  572.                     array_push($keys'WIM');
  573.                 }
  574.                 if ($request->get("coatings-enews")) {
  575.                     array_push($keys'WIC');
  576.                 }
  577.                 // MailChimp API URL
  578.                 $memberID md5(strtolower($email));
  579.                 $dataCenter substr($apiKey,strpos($apiKey,'-')+1);
  580.                 $url 'https://' $dataCenter '.api.mailchimp.com/3.0/lists/' $listID '/members/' $memberID;
  581.                 
  582.                 // member information
  583.                 $json json_encode([
  584.                     'email_address' => $email,
  585.                     'status'        => 'subscribed',
  586.                     'merge_fields'  => [
  587.                         'FNAME'     => $firstname,
  588.                         'LNAME'     => $lastname,
  589.                         'MMERGE3'    => $company,
  590.                         'MMERGE4'    => $contractor_type,
  591.                         'MMERGE5'    => $business_type
  592.                     ],
  593.                     'tags' => $keys
  594.                 ]);
  595.                 
  596.                 $ch curl_init($url);
  597.                 curl_setopt($chCURLOPT_USERPWD'user:' $apiKey);
  598.                 curl_setopt($chCURLOPT_HTTPHEADER, ['Content-Type: application/json']);
  599.                 curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  600.                 curl_setopt($chCURLOPT_TIMEOUT10);
  601.                 curl_setopt($chCURLOPT_CUSTOMREQUEST'PUT');
  602.                 curl_setopt($chCURLOPT_SSL_VERIFYPEERfalse);
  603.                 curl_setopt($chCURLOPT_POSTFIELDS$json);
  604.                 $result curl_exec($ch);
  605.                 $httpCode curl_getinfo($chCURLINFO_HTTP_CODE);
  606.                 curl_close($ch);
  607.                 
  608.                 if ($httpCode != 200) {
  609.                     $httpErrorCode $httpCode;
  610.                 }
  611.                 
  612.                 // end mailchimp
  613.                 
  614.                 if ($request->get("enews")) {
  615.                     $emailHelper->sendEmail(
  616.                         ["rcs@rooferscoffeeshop.com"],
  617.                         "New submission from the \"Week in Roofing\" sign-up form.",
  618.                         [
  619.                             ["p" => "New submission from the \"Week in Roofing\" sign-up form."],
  620.                             ["table" => [
  621.                                 "First Name" => $firstname,
  622.                                 "Last Name" => $lastname,
  623.                                 "Email Address" => $email,
  624.                                 "Company" => $company,
  625.                                 "Country" => $country,
  626.                                 "Type of Work" => $contractor_type,
  627.                                 "Type of Business" => $business_type,
  628.                             ]],
  629.                         ]
  630.                     );
  631.                 }
  632.                 if ($request->get("metal-enews")) {
  633.                     $emailHelper->sendEmail(
  634.                         ["rcs@rooferscoffeeshop.com"],
  635.                         "New submission from the \"Week in Metal\" sign-up form.",
  636.                         [
  637.                             ["p" => "New submission from the \"Week in Metal\" sign-up form."],
  638.                             ["table" => [
  639.                                 "First Name" => $firstname,
  640.                                 "Last Name" => $lastname,
  641.                                 "Email Address" => $email,
  642.                                 "Company" => $company,
  643.                                 "Country" => $country,
  644.                                 "Type of Work" => $contractor_type,
  645.                                 "Type of Business" => $business_type,
  646.                             ]],
  647.                         ]
  648.                     );
  649.                 }
  650.                 if ($request->get("coatings-enews")) {
  651.                     $emailHelper->sendEmail(
  652.                         ["rcs@rooferscoffeeshop.com"],
  653.                         "New submission from the \"Week in Coatings\" sign-up form.",
  654.                         [
  655.                             ["p" => "New submission from the \"Week in Coatings\" sign-up form."],
  656.                             ["table" => [
  657.                                 "First Name" => $firstname,
  658.                                 "Last Name" => $lastname,
  659.                                 "Email Address" => $email,
  660.                                 "Company" => $company,
  661.                                 "Country" => $country,
  662.                                 "Type of Work" => $contractor_type,
  663.                                 "Type of Business" => $business_type,
  664.                             ]],
  665.                         ]
  666.                     );
  667.                 }
  668.                 // store the lead
  669.                 $content null;
  670.                 
  671.                 $lead_custom $request->get("lead_custom");
  672.                 $lead $leadHelper->saveLead($lead$content$request$lead_custom);
  673.                 
  674.                 if(isset($httpErrorCode)) {
  675.                     $lead->setComments("MailChimp http code: {$httpErrorCode}");
  676.                 }
  677.                 
  678.                 $em $this->getDoctrine()->getManager();
  679.                 $em->persist($lead);
  680.                 $em->flush();
  681.                 
  682.                 if(isset($httpErrorCode)) {
  683.                     $this->addFlash("warning""An error occurred while attempting to add you to our mailing list. Please try again later.");
  684.                     return new RedirectResponse($request->headers->get('referer'));
  685.                 }
  686.                 
  687.                 //$this->addFlash("success", "Thank you for signing up for the RCS Week in Review.");
  688.                 //return new RedirectResponse($request->headers->get('referer'));
  689.                 $enewsSignupSuccess true;
  690.                 
  691.             }
  692.             
  693.             catch (\Exception $e) {
  694.                 $this->addFlash("warning"$e->getMessage());
  695.                 return new RedirectResponse($request->headers->get('referer'));
  696.             }
  697.             
  698.         }
  699.         else {
  700.             $lead $request->get("lead");
  701.             $lead_custom $request->get("lead_custom");
  702.             $lead $leadHelper->saveLead($leadnull$request$lead_custom);
  703.             $em $this->getDoctrine()->getManager();
  704.             $em->persist($lead);
  705.             $em->flush();
  706.         }
  707.         
  708.         if($siteSignupSuccess) {
  709.             return new RedirectResponse('/welcome-activation');
  710.         }
  711.         
  712.         if($enewsSignupSuccess) {
  713.             // $this->addFlash("success", "Thank you for signing up for the RCS Week in Roofing.");
  714.             return new RedirectResponse('/thank-you-wir');
  715.         }
  716.         
  717.     }
  718.     
  719.     /**
  720.      * @Route("/sign-up", name="new-sign-up-form")
  721.      */
  722.     public function viewNewSignUp (
  723.     
  724.     ) {
  725.         
  726.         return $this->defaultRender("forms/new-sign-up.html.twig", [
  727.             "firstname" => "",
  728.             "lastname" => "",
  729.             "username" => "",
  730.             "email" => "",
  731.             "address1" => "",
  732.             "address2" => "",
  733.             "city" => "",
  734.             "state" => "",
  735.             "zip" => "",
  736.             "company" => "",
  737.             "message" => array (
  738.             
  739.             ),
  740.             "meta" => array (
  741.                "breadcrumbs" => [
  742.                    [
  743.                        "title" => "Sign Up",
  744.                        "href" => "/sign-up",
  745.                    ]
  746.                ]
  747.            )
  748.         ]);
  749.     }
  750.     
  751.     
  752.     
  753.     
  754.     
  755.     
  756.     
  757.     
  758.     /**
  759.      * @Route("/activate-account", name="activate", methods={"POST"})
  760.      */
  761.     public function activateAccount (
  762.         Request $request,
  763.         UserHelper $userHelper,
  764.         ContentHelper $contentHelper
  765.     ) {
  766.         
  767.         $id $request->get("id");
  768.         $token $request->get("token");
  769.         $rclubProdId $request->get("rclubProdId");
  770.         $rsp $userHelper->activateAccount($id$token);
  771.         
  772.         if ($rsp["status"]) {
  773.             
  774.             //redirect to purchase page if rclubProdId is set
  775.             if($rclubProdId) {
  776.                 $user $userHelper->getUserById($id);
  777.                 if ($user) {
  778.             
  779.                     // use the current cart or create one
  780.                    $purchase $user->getActivePurchase();
  781.                    if (!$purchase) {
  782.                        $purchase = new Purchase();
  783.                    }
  784.                    
  785.                    //Remove all items since we're going straight to checkout
  786.                    foreach($purchase->getItems() as $item) {
  787.                        //$product = $item->getProduct();
  788.                        //if($product->getType() == Product::PRODUCT_TYPE_MEMBERSHIP) {
  789.                            $purchase->removeItem($item);
  790.                        //}
  791.                    }
  792.                    
  793.                    $newItem = new PurchaseItem();
  794.                    
  795.                    $newItem->setProduct($contentHelper->getProductById($rclubProdId));
  796.                    $newItem->setType(PurchaseItem::TYPE_MEMBERSHIP);
  797.                    $newItem->setPurchase($purchase);
  798.                    
  799.                    // add to the current Item
  800.                    $purchase->setCurrentItem($newItem);
  801.                    $purchase->setUser($user);
  802.                    $purchase->setDiscount(0);
  803.                    
  804.                    $manager $this->getDoctrine()->getManager();
  805.                    $manager->persist($purchase);
  806.                    $manager->flush();
  807.                    
  808.                    $this->addFlash("success""You have successfully activated your account! Please complete your purchase below to join the R-Club.");
  809.                    return $this->redirectToRoute("purchase", [
  810.                    
  811.                    ]);
  812.         
  813.                }
  814.             }
  815.             /*return $this->defaultRender("/", [
  816.                 "message" => array (
  817.                     "type" => "success",
  818.                     "text" => $rsp["message"],
  819.                 )
  820.             ]);*/
  821.             
  822.             //$this->addFlash("success", $rsp["message"]);
  823.             //return $this->redirect("/");
  824.             return $this->redirect("/welcome-to-rcs");
  825.             
  826.             //$this->addFlash("success", $rsp["message"]);
  827.             //return $this->redirect('http://staging.rooferscoffeeshop.com/post-a-classified-ad/2');
  828.         
  829.         
  830.         else {
  831.             return $this->defaultRender("forms/send-activation.html.twig", [
  832.                 "type" => "warning",
  833.                 "text" => $rsp["message"],
  834.             ]);
  835.         }
  836.         
  837.         
  838.         /*
  839.         try {
  840.             $id = $request->get("id");
  841.             $token = $request->get("token");
  842.             
  843.             $user = $userHelper->getUserById($id);
  844.             $expires = $user->getActivationExpires();
  845.             
  846.             if ($user->getActivationToken() == $token && 
  847.                 new \DateTime("now") < $expires
  848.             ) {
  849.                 $user->setActivationToken(null);
  850.                 $user->setActivationExpires(null);
  851.                 // $user->setIsActive(1);
  852.                 $user->setStatus(1);
  853.                 
  854.                 $em = $this->getDoctrine()->getManager();
  855.                 $em->persist($user);
  856.                 $em->flush();
  857.                 $em->clear();
  858.                 
  859.                 return $this->defaultRender("forms/sign-in.html.twig", [
  860.                     "message" => array (
  861.                         "type" => "success",
  862.                         "text" => "The account has been activated. You may now sign in.",
  863.                     ),
  864.                 ]);
  865.             }
  866.         } 
  867.         
  868.         catch (ResourceNotFoundException $e) {
  869.             // ... ignore
  870.         }
  871.         
  872.         return $this->defaultRender("forms/send-activation.html.twig", [
  873.             "message" => array (
  874.                 "type" => "warning",
  875.                 "text" => "The provided token was not found in the system. It is possible that it has expired. If the token has expired, you will need to sign up again.",
  876.             ),
  877.         ]);
  878.         */
  879.         
  880.     }
  881.     
  882.     /**
  883.      * @Route("/activate-account/{id}/{token}/{rclubProdId}", name="view-activation-form")
  884.      */
  885.     public function viewActivateAccount (
  886.         UserHelper $userHelper,
  887.         $id "",
  888.         $token "",
  889.         $rclubProdId ""
  890.     ) {
  891.         try {
  892.             $user $userHelper->getUserById($id);
  893.             $expires $user->getActivationExpires();
  894.             if ($token == $user->getActivationToken() && 
  895.                 new \DateTime("now") < $expires 
  896.             ) {
  897.                 return $this->defaultRender("forms/activate.html.twig", [
  898.                     "username" => $user->getUsername(),
  899.                     "id" => $id,
  900.                     "token" => $token,
  901.                     "rclubProdId" => $rclubProdId,
  902.                 ]);
  903.             }
  904.         } catch (ResourceNotFoundException $e) {
  905.             // ... ignore
  906.         }
  907.         
  908.         return $this->defaultRender("forms/send-activation.html.twig", [
  909.             "message" => array (
  910.                 "type" => "warning",
  911.                 "text" => "The provided token was not found in the system. It is possible that it has expired. If the token has expired, you will need to sign up again or re-send the activation link.",
  912.             ),
  913.         ]);
  914.     }
  915.     
  916.     /**
  917.      * @Route("/send-activation", name="send-activation", methods={"POST"})
  918.      */
  919.     public function sendActivation (
  920.         Request $request,
  921.         UserHelper $userHelper,
  922.         EmailHelper $emailHelper
  923.     ) {
  924.         
  925.         $email $request->get("email");
  926.         $resp $userHelper->sendActivation($email);
  927.                  
  928.         if ($resp["status"]) {
  929.             return $this->defaultRender("forms/send-activation.html.twig", [
  930.                 "message" => array (
  931.                     "type" => "success",
  932.                     "text" => $resp["message"],
  933.                 )
  934.             ]);
  935.         }
  936.         
  937.         return $this->defaultRender("forms/send-activation.html.twig", [
  938.             "message" => array (
  939.                 "type" => "warning",
  940.                 "text" => $resp["message"],
  941.             )
  942.         ]);
  943.         
  944.         /*
  945.         try {
  946.             $email = $request->get("email");
  947.             $user = $userHelper->getUserByEmail($email);
  948.             $uid = $user->getId();
  949.             $token = $user->getActivationToken();
  950.             $expires = $user->getActivationExpires();
  951.             
  952.             $pooled = $emailHelper->sendEmail($email, "Account Activation Link", [
  953.                 ["p" => "Hello {$user->getFullName()},"],
  954.                 ["p" => "You recently requested to receive an activation link for your RoofersCoffeeShop account. Click the button below to activate it."],
  955.                 ["button" => [
  956.                     "text" => "Activate Account",
  957.                     "href" => "https://rooferscoffeeshop.com/activate-account/{$uid}/{$token}",
  958.                 ]],
  959.                 ["p" => "If you did not request a password reset, please ignore this email or reply to let us know. This password reset link is only valid for the next 2 hours."],
  960.             ]);
  961.             
  962.             if ($pooled) {
  963.                 return $this->defaultRender("forms/send-activation.html.twig", [
  964.                     "message" => array (
  965.                         "type" => "success",
  966.                         "text" => "The activation link has been sent to that e-mail address.",
  967.                     )
  968.                 ]);
  969.             } 
  970.             
  971.             return $this->defaultRender("forms/send-activation.html.twig", [
  972.                 "message" => array (
  973.                     "type" => "warning",
  974.                     "text" => "An error occurred while trying to send a system e-mail. If this error continues to occur please contact support.",
  975.                 )
  976.             ]);
  977.             
  978.         } catch (ResourceNotFoundException $e) {
  979.             
  980.         }
  981.         
  982.         return $this->defaultRender("forms/send-activation.html.twig", [
  983.             "message" => array (
  984.                 "type" => "warning",
  985.                 "text" => "No account found matching that criteria.",
  986.             )
  987.         ]);
  988.         */
  989.         
  990.     }
  991.     
  992.     /**
  993.      * @Route("/send-activation", name="send-activation-form")
  994.      */
  995.     public function viewSendActivation (
  996.         UserHelper $userHelper
  997.     ) {
  998.         return $this->defaultRender("forms/send-activation.html.twig", [
  999.             "message" => array (),
  1000.         ]);
  1001.     }
  1002.     /**
  1003.      * @Route("/mfa/{id}/{token}", name="view-mfa-form")
  1004.      */
  1005.     public function viewMfa (
  1006.         UserHelper $userHelper,
  1007.         $id "",
  1008.         $token ""
  1009.     ) {
  1010.         try {
  1011.             $user $userHelper->getUserById($id);
  1012.             $expires $user->getMfaTokenExpires();
  1013.             if ($token == $user->getMfaToken() && 
  1014.                 new \DateTime("now") < $expires 
  1015.             ) {
  1016.                 return $this->defaultRender("forms/mfa.html.twig", [
  1017.                     "username" => $user->getUsername(),
  1018.                     "id" => $id,
  1019.                     "token" => $token,
  1020.                 ]);
  1021.             }
  1022.         } catch (ResourceNotFoundException $e) {
  1023.             // ... ignore
  1024.         }
  1025.         
  1026.         return $this->defaultRender("forms/sign-in.html.twig", [
  1027.             "message" => array (
  1028.                 "type" => "warning",
  1029.                 "text" => "The provided token was not found in the system. It is possible that it has expired. Try signing in again.",
  1030.             ),
  1031.         ]);
  1032.     }
  1033.     /**
  1034.      * @Route("/mfasignin", name="mfasignin", methods={"POST"})
  1035.      */
  1036.     public function mfaSignIn (
  1037.         Request $request,
  1038.         UserHelper $userHelper
  1039.         //DoctrineTokenProvider $doctrineTokenProvider
  1040.     ) {
  1041.         
  1042.         $id $request->get("id");
  1043.         $token $request->get("token");
  1044.         $code $request->get("code");
  1045.         $rsp $userHelper->signInMfa($id$token$code);
  1046.         
  1047.         if ($rsp["status"]) {
  1048.             
  1049.             /*return $this->defaultRender("/", [
  1050.                 "message" => array (
  1051.                     "type" => "success",
  1052.                     "text" => $rsp["message"],
  1053.                 )
  1054.             ]);*/
  1055.             $session $request->getSession();
  1056.             $nRoute $session->get("non_sign_in_route");
  1057.             $path = !empty($nRoute["path"]) ? $nRoute["path"] : "/";
  1058.             $user $userHelper->getUserById($id);
  1059.             $username $user->getUsername();
  1060.             
  1061.             $this->addFlash("success""You have successfully logged in.");
  1062.             $response = new RedirectResponse($path);
  1063.             //$response = $this->setRememberMe($request, $response, $doctrineTokenProvider, $username);
  1064.             return $response;
  1065.             
  1066.             //return $this->redirect("/");
  1067.             
  1068.             //$this->addFlash("success", $rsp["message"]);
  1069.             //return $this->redirect('http://staging.rooferscoffeeshop.com/post-a-classified-ad/2');
  1070.         
  1071.         
  1072.         else {
  1073.             return $this->defaultRender("forms/mfa.html.twig", [
  1074.                 //"username" => $user->getUsername(),
  1075.                 "id" => $id,
  1076.                 "token" => $token,
  1077.                 "message" => array (
  1078.                     "type" => "warning",
  1079.                     "text" => $rsp["message"],
  1080.                 )
  1081.             ]);
  1082.         }
  1083.         
  1084.     }
  1085.     //no longer used
  1086.     public function setRememberMe(
  1087.         $request,
  1088.         $response,
  1089.         $doctrineTokenProvider,
  1090.         $username
  1091.     ) {
  1092.         return false;
  1093.         $series base64_encode(random_bytes(64));
  1094.         $tokenValue base64_encode(random_bytes(64));
  1095.         $user $this->user;
  1096.         $doctrineTokenProvider->createNewToken(
  1097.             new PersistentToken(
  1098.                 User::class,
  1099.                 //$user->getUsername(),
  1100.                 $username,
  1101.                 $series,
  1102.                 $tokenValue,
  1103.                 new \DateTime()
  1104.             )
  1105.         );
  1106.         
  1107.         $options = [
  1108.             'name' => 'REMEMBERME',
  1109.             'lifetime' => 604800,
  1110.             'path' => '/',
  1111.             //'domain' => 'staging.rooferscoffeeshop.com',
  1112.             'domain' => null,
  1113.             'secure' => true,
  1114.             'httponly' => true,
  1115.             'samesite' => 'strict',
  1116.         ];
  1117.         //samesite = 
  1118.         //public const SAMESITE_NONE = 'none';
  1119.         //public const SAMESITE_LAX = 'lax';
  1120.         //public const SAMESITE_STRICT = 'strict';
  1121.         $cookieParts = [$series$tokenValue];
  1122.         
  1123.         foreach ($cookieParts as $cookiePart) {
  1124.             if (str_contains($cookiePart":")) {
  1125.                 throw new \InvalidArgumentException(sprintf('$cookieParts should not contain the cookie delimiter "%s".'":"));
  1126.             }
  1127.         }
  1128.         $encodedCookie base64_encode(implode(":"$cookieParts));
  1129.         //$response = new Response();
  1130.         $response->headers->setCookie(
  1131.             new Cookie(
  1132.                 $options['name'],
  1133.                 //$this->encodeCookie([$series, $tokenValue]),
  1134.                 $encodedCookie,
  1135.                 time() + $options['lifetime'],
  1136.                 $options['path'],
  1137.                 $options['domain'],
  1138.                 $options['secure'] ?? $request->isSecure(),
  1139.                 $options['httponly'],
  1140.                 false,
  1141.                 $options['samesite']
  1142.             )
  1143.         );
  1144.         return $response;
  1145.     }
  1146.     
  1147.     /**
  1148.      * @Route("/account", methods={"POST"}, name="post-account")
  1149.      */
  1150.     public function updateAccount (
  1151.         Request $request,
  1152.         UserHelper $userHelper
  1153.     ) {
  1154.         // if we have a current user
  1155.         if ($this->user) {
  1156.             // grab the fields
  1157.             $data = [];
  1158.             
  1159.             if ($request->get("firstname")) {
  1160.                 $data["firstname"] = $request->get("firstname");
  1161.             }
  1162.             
  1163.             if ($request->get("lastname")) {
  1164.                 $data["lastname"] = $request->get("lastname");
  1165.             }
  1166.             
  1167.             if ($request->get("displayname")) {
  1168.                 $data["displayname"] = $request->get("displayname");
  1169.             }
  1170.             
  1171.             if ($request->get("username")) {
  1172.                 $data["username"] = $request->get("username");
  1173.             }
  1174.             
  1175.             if ($request->get("email")) {
  1176.                 $data["email"] = $request->get("email");
  1177.             }
  1178.             
  1179.             if ($request->get("password1")) {
  1180.                 $data["password1"] = $request->get("password1");
  1181.                 $data["password2"] = $request->get("password2");
  1182.                 $data["password3"] = $request->get("password3");
  1183.             }
  1184.             
  1185.             // user avatar
  1186.             if ($request->files->get("avatar")) {
  1187.                 $data["avatar"] = $request->files->get("avatar");
  1188.                 $mime =  $data["avatar"]->getMimeType();
  1189.                 if(!in_array($mime, ["image/jpg""image/jpeg""image/png""image/gif"])) {
  1190.                     $this->addFlash("danger""Only PNG, JPG, and GIF file types are allowed.");
  1191.                     return new RedirectResponse($request->headers->get('referer'));
  1192.                 }
  1193.             }
  1194.             
  1195.             else if ($request->get("remove_avatar")) {
  1196.                 $data["remove_avatar"] = true;
  1197.             }
  1198.             
  1199.             //Update notifications 
  1200.             $data["usermeta"] = [];
  1201.             $notifications $request->get("notifications");
  1202.             if(empty($notifications)) {
  1203.                 $notifications = [];
  1204.             }
  1205.             $data["usermeta"]["member_notification_forum"] = in_array("forum"$notifications);
  1206.             $data["usermeta"]["member_notification_page"] = in_array("page"$notifications);
  1207.             $data["usermeta"]["member_notification_classifieds"] = in_array("classifieds"$notifications);
  1208.             
  1209.             
  1210.             $rsp $userHelper->updateAccount(
  1211.                 $this->user->getId(),
  1212.                 $data
  1213.             );
  1214.             $this->addFlash($rsp["type"], $rsp["message"]);
  1215.         }
  1216.         
  1217.         return $this->redirectToRoute("account");
  1218.     }
  1219.     
  1220.     
  1221.     /**
  1222.      * @Route("/account/profile", methods={"POST"}, name="post-account-profile")
  1223.      */
  1224.     public function updateAccountProfile (
  1225.         Request $request,
  1226.         ContactHelper $contactHelper,
  1227.         EmailHelper $emailHelper
  1228.     ) {
  1229.         
  1230.         $user $this->user;
  1231.         // if we have a current user
  1232.         if($user) {
  1233.             
  1234.             $contact $user->getContact();
  1235.             if(!$contact) {
  1236.                 $contact = new Contact();
  1237.                 $user->setContact($contact);
  1238.                 $entityManager $this->getDoctrine()->getManager();
  1239.                 $entityManager->persist($user);
  1240.                 $entityManager->flush();
  1241.             }
  1242.             
  1243.             $contactHelper->updateContact($contact->getId(), $request->request->all());
  1244.             $this->addFlash("success""Profile updated.");
  1245.             
  1246.             $emailHelper->sendEmail(
  1247.                 ["rcs@rooferscoffeeshop.com"],
  1248.                 "Profile Updated - {$user->getUsername()}",
  1249.                 [
  1250.                     ["p" => "{$user->getUsername()} has updated their account's profile information."],
  1251.                     ["p" => "Visit the User Dashboard to view these changes."],
  1252.                     ["button" => [
  1253.                         "text" => "User Dashboard",
  1254.                         "href" => "https://www.rooferscoffeeshop.com/user-dashboard",
  1255.                     ]],
  1256.                 ]
  1257.             );
  1258.             
  1259.         }
  1260.         
  1261.         return $this->redirectToRoute("account", [
  1262.            "slug" => "profile",
  1263.         ]);
  1264.     }
  1265.     
  1266.     /**
  1267.      * @Route("/account/content/{type}", name="account-content-filter")
  1268.      */
  1269.     public function viewAccountContentType (
  1270.         Request $request,
  1271.         UserHelper $userHelper,
  1272.         $type ""
  1273.     ) {
  1274.         if (!$this->user) {
  1275.             return $this->redirect("/sign-in");
  1276.         }
  1277.         $user $this->user;
  1278.         
  1279.         return $this->defaultRender("forms/user-account.html.twig", [
  1280.             "user" => $user,
  1281.             "slug" => "content",
  1282.             "type" => $type,
  1283.             
  1284.             "meta" => [
  1285.                 "breadcrumbs" => [
  1286.                     [
  1287.                         "title" => "Your Account",
  1288.                         "href" => "/account",
  1289.                     ]
  1290.                 ]
  1291.             ]
  1292.         ]);
  1293.         
  1294.         
  1295.     }
  1296.     
  1297.     /**
  1298.      * @Route("/account/membership/cancel", methods={"POST"}, name="post-account-membership-cancel")
  1299.      */
  1300.     public function cancelAccountMembership (
  1301.         Request $request,
  1302.         UserHelper $userHelper,
  1303.         OrderHelper $orderHelper,
  1304.         EmailHelper $emailHelper
  1305.     ) {
  1306.         if (!$this->user) {
  1307.             return $this->redirect("/sign-in");
  1308.         }
  1309.         $user $this->user;
  1310.         
  1311.         $manager $this->getDoctrine()->getManager();
  1312.         $item $manager->getRepository(PurchaseItem::class)
  1313.             ->findOneBy([
  1314.                "id" => $request->get("item_id"),
  1315.             ]);
  1316.         
  1317.         $item->setStatus(PurchaseItem::STATUS_ACTIVE);
  1318.         $manager->persist($item);
  1319.         $manager->flush();
  1320.         
  1321.         //send email
  1322.         $message = [];
  1323.         $message[] = ["p" => "Your R-Club membership has been cancelled and will not auto-renew."];
  1324.         $message[] = ["a" => ["href" => "rooferscoffeeshop.com/account""text" => "Go to your account page to turn auto-renew back on or update your settings."]];
  1325.         
  1326.         $emailHelper->sendEmail (
  1327.             [$user->getEmail()],
  1328.             "R-Club Auto-Renew Cancelled",
  1329.             $message
  1330.         );
  1331.         
  1332.         $this->addFlash("success""Your membership has been cancelled and will not auto-renew.");
  1333.         return $this->redirectToRoute("account", [
  1334.            "slug" => "membership",
  1335.         ]);
  1336.     }
  1337.     
  1338.     /**
  1339.      * @Route("/account/membership/continue", methods={"POST"}, name="post-account-membership-continue")
  1340.      */
  1341.     public function continueAccountMembership (
  1342.         Request $request,
  1343.         UserHelper $userHelper,
  1344.         OrderHelper $orderHelper,
  1345.         EmailHelper $emailHelper
  1346.     ) {
  1347.         if (!$this->user) {
  1348.             return $this->redirect("/sign-in");
  1349.         }
  1350.         $user $this->user;
  1351.         
  1352.         $manager $this->getDoctrine()->getManager();
  1353.         $item $manager->getRepository(PurchaseItem::class)
  1354.             ->findOneBy([
  1355.                "id" => $request->get("item_id"),
  1356.             ]);
  1357.         
  1358.         $item->setStatus($item->getPaymentFailed() ? PurchaseItem::STATUS_ACTIVE_RENEWING_FINAL PurchaseItem::STATUS_ACTIVE_RENEWING);
  1359.         $manager->persist($item);
  1360.         $manager->flush();
  1361.         
  1362.         //send email
  1363.         $message = [];
  1364.         $message[] = ["p" => "Thank you for re-activating your R-Club membership."];
  1365.         $message[] = ["a" => ["href" => "rooferscoffeeshop.com/account""text" => "Go to your account page to view your renewal information."]];
  1366.         
  1367.         $emailHelper->sendEmail (
  1368.             [$user->getEmail()],
  1369.             "R-Club Auto-Renew Activated",
  1370.             $message
  1371.         );
  1372.         
  1373.         $this->addFlash("success""Your membership has been re-activated and will now automatically renew.");
  1374.         return $this->redirectToRoute("account", [
  1375.            "slug" => "membership",
  1376.         ]);
  1377.     }
  1378.     
  1379.     /**
  1380.      * @Route("/account/membership", methods={"POST"}, name="post-account-membership")
  1381.      */
  1382.     public function updateAccountMembership (
  1383.         Request $request,
  1384.         UserHelper $userHelper,
  1385.         OrderHelper $orderHelper
  1386.     ) {
  1387.         
  1388.         if (!$this->user) {
  1389.             return $this->redirect("/sign-in");
  1390.         }
  1391.         $user $this->user;
  1392.         
  1393.         $payment $request->get("payment");
  1394.         $card $request->get("card");
  1395.         
  1396.         //expiration date
  1397.         $card["card_expires"] = $card["card_expires_month"].$card["card_expires_year"];
  1398.         
  1399.         if (!$payment || !isset($payment["terms"])) {
  1400.             $this->addFlash("warning""You must accept the terms and conditions.");
  1401.             return $this->redirectToRoute("account", [
  1402.                "slug" => "membership",
  1403.             ]);
  1404.         }
  1405.         
  1406.         $result $orderHelper->generateToken(
  1407.            $payment["firstname"],
  1408.            $payment["lastname"],
  1409.            $payment["company"],
  1410.            $payment["address1"],
  1411.            $payment["address2"],
  1412.            $payment["city"],
  1413.            $payment["state"],
  1414.            $payment["zip"],
  1415.            $payment["country"],
  1416.            $payment["email"],
  1417.            $payment["phone"],
  1418.            $_SERVER["REMOTE_ADDR"],
  1419.            $card["card_number"],
  1420.            $card["card_expires"],
  1421.            $card["card_csc"]
  1422.         );
  1423.         
  1424.         if ($result["result"] == "APPROVAL" || $result["result"] == "APPROVED") {
  1425.             
  1426.             $last4 $card["card_number"];
  1427.             $last4 preg_replace("/[^0-9]/"''$last4);
  1428.             $last4 substr($last4, -4);
  1429.             
  1430.             $user->setUsermetum("has_payment_info""1");
  1431.             $user->setUsermetum("payment_first_name"$payment["firstname"]);
  1432.             $user->setUsermetum("payment_last_name"$payment["lastname"]);
  1433.             $user->setUsermetum("payment_company"$payment["company"]);
  1434.             $user->setUsermetum("payment_address_line_1"$payment["address1"]);
  1435.             $user->setUsermetum("payment_address_line_2"$payment["address2"]);
  1436.             $user->setUsermetum("payment_city"$payment["city"]);
  1437.             $user->setUsermetum("payment_state_province"$payment["state"]);
  1438.             $user->setUsermetum("payment_postal_code"$payment["zip"]);
  1439.             $user->setUsermetum("payment_country"$payment["country"]);
  1440.             $user->setUsermetum("payment_email"$payment["email"]);
  1441.             $user->setUsermetum("payment_phone"$payment["phone"]);
  1442.             $user->setUsermetum("payment_last4"$last4);
  1443.             $user->setUsermetum("payment_exp"$card["card_expires"]);
  1444.             //$user->setUsermetum("payment_cvv2", $card["card_csc"]);
  1445.             $user->setUsermetum("payment_token"$result["token"]);
  1446.             $user->setUsermetum("payment_token_response"$result["token_response"]);
  1447.             
  1448.             $manager $this->getDoctrine()->getManager();
  1449.             $manager->persist($user);
  1450.             $manager->flush();
  1451.             
  1452.             $this->addFlash("success""Membership settings updated.");
  1453.             return $this->redirectToRoute("account", [
  1454.                //"slug" => "membership",
  1455.             ]);
  1456.         }
  1457.         else {
  1458.             $this->addFlash("warning""Their was an error while updating your payment information. Response: {$result["result"]}");
  1459.             return $this->redirectToRoute("account", [
  1460.                "slug" => "membership",
  1461.             ]);
  1462.         }
  1463.         
  1464.         
  1465.         
  1466.     }
  1467.     
  1468.     /**
  1469.      * @Route("/account/{slug}/{id}", 
  1470.      *      name="account",
  1471.      *      defaults={"slug": "", "id": ""}
  1472.      * )
  1473.      */
  1474.     public function viewAccount (
  1475.         UserHelper $userHelper,
  1476.         Request $request,
  1477.         $slug "",
  1478.         $id ""
  1479.     ) {
  1480.         if (!$this->user) {
  1481.             return $this->redirect("/sign-in");
  1482.         }
  1483.         $user $this->user;
  1484.         $manager $this->getDoctrine()->getManager();
  1485.         $purchases $user->getPurchases();
  1486.         $purchase null;
  1487.         
  1488.         if (!$slug) {
  1489.             $slug "account";
  1490.         }
  1491.         
  1492.         if ($slug == "order" && $id) {
  1493.             // show the order details
  1494.             $purchase $manager->getRepository(Purchase::class)
  1495.                 ->findOneBy([
  1496.                     "id" => $id
  1497.                 ]);
  1498.             
  1499.             if (!$purchase || $purchase->getUser()->getId() != $user->getId()) {
  1500.                 $purchase null;
  1501.             }
  1502.         }
  1503.         
  1504.         $customers $user->getCompanies();
  1505.         
  1506.         $membership_item "";
  1507.         $membership_product "";
  1508.         $will_renew false;
  1509.         //Get the current purchase item used to activate the user's membership
  1510.         if($user->isMember()) {
  1511.             $now = new \DateTime();
  1512.             foreach($purchases as $p) {
  1513.                 $items $p->getItems();
  1514.                 foreach($items as $item) {
  1515.                     if(($item->getStatus() >= PurchaseItem::STATUS_ACTIVE) && ($item->getType() == PurchaseItem::TYPE_MEMBERSHIP) && ($item->getExpiresAt() > $now)) {
  1516.                         $membership_item $item;
  1517.                         $membership_product $item->getProduct();
  1518.                         $will_renew = ($item->getStatus() >= PurchaseItem::STATUS_ACTIVE_RENEWING true false);
  1519.                     }
  1520.                 }
  1521.             }
  1522.         }
  1523.         
  1524.         $payment false;
  1525.         if($slug == "membership") {
  1526.             if($user->getUserMetaValueByKey("has_payment_info")) {
  1527.                 $payment = [];
  1528.                 $payment["firstname"] = $user->getUserMetaValueByKey("payment_first_name");
  1529.                 $payment["lastname"] = $user->getUserMetaValueByKey("payment_last_name");
  1530.                 $payment["company"] = $user->getUserMetaValueByKey("payment_company");
  1531.                 $payment["address1"] = $user->getUserMetaValueByKey("payment_address_line_1");
  1532.                 $payment["address2"] = $user->getUserMetaValueByKey("payment_address_line_2");
  1533.                 $payment["city"] = $user->getUserMetaValueByKey("payment_city");
  1534.                 $payment["state"] = $user->getUserMetaValueByKey("payment_state_province");
  1535.                 $payment["zip"] = $user->getUserMetaValueByKey("payment_postal_code");
  1536.                 $payment["country"] = $user->getUserMetaValueByKey("payment_country");
  1537.                 $payment["email"] = $user->getUserMetaValueByKey("payment_email");
  1538.                 $payment["phone"] = $user->getUserMetaValueByKey("payment_phone");
  1539.             }
  1540.         }
  1541.         
  1542.         return $this->defaultRender("forms/user-account.html.twig", [
  1543.             "user" => $user,
  1544.             "purchases" => $purchases,
  1545.             "purchase" => $purchase,
  1546.             "slug" => $slug,
  1547.             "customers" => $customers,
  1548.             "membership_item" => $membership_item,
  1549.             "membership_product" => $membership_product,
  1550.             "will_renew" => $will_renew,
  1551.             "payment" => $payment,
  1552.             
  1553.             "meta" => [
  1554.                 "breadcrumbs" => [
  1555.                     [
  1556.                         "title" => "Your Account",
  1557.                         "href" => "/account",
  1558.                     ]
  1559.                 ]
  1560.             ]
  1561.         ]);
  1562.     }
  1563.     
  1564.     /**
  1565.      * @Route("/admin-account/membership/{id}", methods={"GET"}, name="admin-account-membership")
  1566.      */
  1567.     public function adminAccountMembership(
  1568.         Request $request,
  1569.         UserHelper $userHelper,
  1570.         $id ""
  1571.     ) {
  1572.         //Admin check
  1573.         $access false;
  1574.         if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  1575.             $user $this->getUser();
  1576.             if($user) {
  1577.                 if($user->isAdmin()) {
  1578.                     $access true;
  1579.                 }
  1580.             }
  1581.         }
  1582.         
  1583.         if(!$access) {
  1584.             $this->addFlash("warning""This page is only accessible to site administrators.");
  1585.             return $this->redirectToRoute("/");
  1586.         }
  1587.         
  1588.         $member "";
  1589.         if($id) {
  1590.             $member $userHelper->getUserById($id);
  1591.         }
  1592.         $manager $this->getDoctrine()->getManager();
  1593.         $purchases $member->getPurchases();
  1594.         $purchase null;
  1595.         
  1596.         $membership_item "";
  1597.         $membership_product "";
  1598.         $will_renew false;
  1599.         $last_membership_item "";
  1600.         $last_membership_product "";
  1601.         $renewal_price "";
  1602.         //Get the current purchase item used to activate the user's membership
  1603.         if($member->isMember()) {
  1604.             $now = new \DateTime();
  1605.             foreach($purchases as $p) {
  1606.                 $items $p->getItems();
  1607.                 foreach($items as $item) {
  1608.                     if(($item->getStatus() >= PurchaseItem::STATUS_ACTIVE) && ($item->getType() == PurchaseItem::TYPE_MEMBERSHIP) && ($item->getExpiresAt() > $now)) {
  1609.                         $membership_item $item;
  1610.                         $membership_product $item->getProduct();
  1611.                         $will_renew = ($item->getStatus() >= PurchaseItem::STATUS_ACTIVE_RENEWING true false);
  1612.                         $renewal_price $membership_product->getPrice();
  1613.                         $old_coupons $p->getCoupons();
  1614.                         foreach($old_coupons as $coupon) {
  1615.                             if($coupon->getProductType() == Coupon::PRODUCT_TYPE_MEMBERSHIP
  1616.                                 && ($coupon->getRecurringType() == Coupon::RECURRING_UNLIMITED
  1617.                                 || ($coupon->getRecurringType() == Coupon::RECURRING_SET_MONTHS && $coupon->getMonthsRecurring() > $item->getMonthsRenewed()))
  1618.                             ) {
  1619.                                 switch ($coupon->getType()) {
  1620.                 
  1621.                                     case Coupon::TYPE_DISCOUNT:
  1622.                                         $amount $coupon->getAmount();
  1623.                                         if (strpos($amount".") === false) {
  1624.                                             $amount "{$amount}00";
  1625.                                         }
  1626.                                         $amount preg_replace("/[^0-9]*/"""$amount);
  1627.                                         $renewal_price $renewal_price - (double)$amount;
  1628.                                         break;
  1629.                                         
  1630.                                     case Coupon::TYPE_PERCENTAGE:
  1631.                                         $amount $coupon->getAmount();
  1632.                                         $amount = (double) $amount 100;
  1633.                                         $amount = ($renewal_price $amount);
  1634.                                         $renewal_price $renewal_price $amount;
  1635.                                         break;
  1636.                                         
  1637.                                     case Coupon::TYPE_FREE_PRODUCT:
  1638.                                         $couponProducts $coupon->getProducts();
  1639.                                         if ($couponProducts->contains($membership_product)) {
  1640.                                             $renewal_price 0;
  1641.                                         }
  1642.                                         break;
  1643.                                 }
  1644.                                 break;
  1645.                             }
  1646.                         }
  1647.                     }
  1648.                 }
  1649.             }
  1650.         }
  1651.         else {
  1652.             //Get the most recent purchase item used to activate the user's membership
  1653.             $now = new \DateTime();
  1654.             foreach($purchases as $p) {
  1655.                 if(!$last_membership_item) {
  1656.                     $items $p->getItems();
  1657.                     foreach($items as $item) {
  1658.                         if(($item->getStatus() == PurchaseItem::STATUS_INACTIVE) && ($item->getType() == PurchaseItem::TYPE_MEMBERSHIP) && ($item->getExpiresAt() < $now)) {
  1659.                             $last_membership_item $item;
  1660.                             $last_membership_product $item->getProduct();
  1661.                             $renewal_price $last_membership_product->getPrice();
  1662.                             break;
  1663.                         }
  1664.                     }
  1665.                 }
  1666.             }
  1667.         }
  1668.         if($renewal_price) {
  1669.             if($renewal_price 0) {
  1670.                 $renewal_price 0;
  1671.             }
  1672.             $renewal_price "$" number_format(($renewal_price 100), 2);
  1673.         }
  1674.         
  1675.         $payment false;
  1676.         if($member->getUserMetaValueByKey("has_payment_info")) {
  1677.             $payment = [];
  1678.             $payment["firstname"] = $member->getUserMetaValueByKey("payment_first_name");
  1679.             $payment["lastname"] = $member->getUserMetaValueByKey("payment_last_name");
  1680.             $payment["company"] = $member->getUserMetaValueByKey("payment_company");
  1681.             $payment["address1"] = $member->getUserMetaValueByKey("payment_address_line_1");
  1682.             $payment["address2"] = $member->getUserMetaValueByKey("payment_address_line_2");
  1683.             $payment["city"] = $member->getUserMetaValueByKey("payment_city");
  1684.             $payment["state"] = $member->getUserMetaValueByKey("payment_state_province");
  1685.             $payment["zip"] = $member->getUserMetaValueByKey("payment_postal_code");
  1686.             $payment["country"] = $member->getUserMetaValueByKey("payment_country");
  1687.             $payment["email"] = $member->getUserMetaValueByKey("payment_email");
  1688.             $payment["phone"] = $member->getUserMetaValueByKey("payment_phone");
  1689.         }
  1690.         
  1691.         return $this->defaultRender("forms/account/admin-membership.html.twig", [
  1692.             "id" => $id,
  1693.             "member" => $member,
  1694.             "purchases" => $purchases,
  1695.             "purchase" => $purchase,
  1696.             "membership_item" => $membership_item,
  1697.             "membership_product" => $membership_product,
  1698.             "last_membership_item" => $last_membership_item,
  1699.             "last_membership_product" => $last_membership_product,
  1700.             "will_renew" => $will_renew,
  1701.             "renewal_price" => $renewal_price,
  1702.             "payment" => $payment,
  1703.         ]);
  1704.     }
  1705.     
  1706.     /**
  1707.      * @Route("/admin-account/membership-cancel", methods={"POST"}, name="post-admin-account-membership-cancel")
  1708.      */
  1709.     public function adminCancelAccountMembership (
  1710.         Request $request,
  1711.         UserHelper $userHelper,
  1712.         OrderHelper $orderHelper
  1713.     ) {
  1714.         //Admin check
  1715.         $access false;
  1716.         if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  1717.             $admin $this->getUser();
  1718.             if($admin) {
  1719.                 if($admin->isAdmin()) {
  1720.                     $access true;
  1721.                 }
  1722.             }
  1723.         }
  1724.         
  1725.         if(!$access) {
  1726.             $this->addFlash("warning""This page is only accessible to site administrators.");
  1727.             return $this->redirectToRoute("/");
  1728.         }
  1729.         $user_id $request->get("user_id");
  1730.         $user $userHelper->getUserById($user_id);
  1731.         
  1732.         $manager $this->getDoctrine()->getManager();
  1733.         $item $manager->getRepository(PurchaseItem::class)
  1734.             ->findOneBy([
  1735.                "id" => $request->get("item_id"),
  1736.             ]);
  1737.         
  1738.         $item->setStatus(PurchaseItem::STATUS_ACTIVE);
  1739.         $manager->persist($item);
  1740.         $manager->flush();
  1741.         
  1742.         $this->addFlash("success""Membership has been cancelled and will not auto-renew.");
  1743.         return $this->redirectToRoute("admin-account-membership", [
  1744.            "id" => $user_id,
  1745.         ]);
  1746.     }
  1747.     
  1748.     /**
  1749.      * @Route("/admin-account/membership-continue", methods={"POST"}, name="post-admin-account-membership-continue")
  1750.      */
  1751.     public function adminContinueAccountMembership (
  1752.         Request $request,
  1753.         UserHelper $userHelper,
  1754.         OrderHelper $orderHelper
  1755.     ) {
  1756.         //Admin check
  1757.         $access false;
  1758.         if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  1759.             $admin $this->getUser();
  1760.             if($admin) {
  1761.                 if($admin->isAdmin()) {
  1762.                     $access true;
  1763.                 }
  1764.             }
  1765.         }
  1766.         
  1767.         if(!$access) {
  1768.             $this->addFlash("warning""This page is only accessible to site administrators.");
  1769.             return $this->redirectToRoute("/");
  1770.         }
  1771.         $user_id $request->get("user_id");
  1772.         $user $userHelper->getUserById($user_id);
  1773.         
  1774.         $manager $this->getDoctrine()->getManager();
  1775.         $item $manager->getRepository(PurchaseItem::class)
  1776.             ->findOneBy([
  1777.                "id" => $request->get("item_id"),
  1778.             ]);
  1779.         
  1780.         $item->setStatus($item->getPaymentFailed() ? PurchaseItem::STATUS_ACTIVE_RENEWING_FINAL PurchaseItem::STATUS_ACTIVE_RENEWING);
  1781.         $manager->persist($item);
  1782.         $manager->flush();
  1783.         
  1784.         $this->addFlash("success""Membership has been re-activated and will now automatically renew.");
  1785.         return $this->redirectToRoute("admin-account-membership", [
  1786.            "id" => $user_id,
  1787.         ]);
  1788.     }
  1789.     
  1790.     /**
  1791.      * @Route("/admin-account/membership-retry", methods={"POST"}, name="post-admin-account-membership-retry")
  1792.      */
  1793.     public function adminRetryAccountMembership (
  1794.         Request $request,
  1795.         UserHelper $userHelper,
  1796.         OrderHelper $orderHelper,
  1797.         EmailHelper $emailHelper
  1798.     ) {
  1799.         //Admin check
  1800.         $access false;
  1801.         if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  1802.             $admin $this->getUser();
  1803.             if($admin) {
  1804.                 if($admin->isAdmin()) {
  1805.                     $access true;
  1806.                 }
  1807.             }
  1808.         }
  1809.         
  1810.         if(!$access) {
  1811.             $this->addFlash("warning""This page is only accessible to site administrators.");
  1812.             return $this->redirectToRoute("/");
  1813.         }
  1814.         $user_id $request->get("user_id");
  1815.         $user $userHelper->getUserById($user_id);
  1816.         
  1817.         $entityManager $this->getDoctrine()->getManager();
  1818.         $item $entityManager->getRepository(PurchaseItem::class)
  1819.             ->findOneBy([
  1820.                "id" => $request->get("item_id"),
  1821.             ]);
  1822.         
  1823.         /*
  1824.         $item->setStatus($item->getPaymentFailed() ? PurchaseItem::STATUS_ACTIVE_RENEWING_FINAL : PurchaseItem::STATUS_ACTIVE_RENEWING);
  1825.         $entityManager->persist($item);
  1826.         $entityManager->flush();
  1827.         */
  1828.         
  1829.         /* Modified copy of the OrderHelper's "updateExpiredPurchaseItems" function */
  1830.         //TODO: move this to the OrderHelper so code isn't repeated
  1831.         $currentStatus PurchaseItem::STATUS_ACTIVE_RENEWING;
  1832.                 
  1833.         //Do this first: in case there's an error, it won't keep trying to renew
  1834.         $item->setStatus(PurchaseItem::STATUS_INACTIVE);
  1835.         //$item->setExpiresAt(null); //might be useful to see when it expired
  1836.         $entityManager->persist($item);
  1837.         $entityManager->flush();
  1838.         
  1839.         $purchase_completed false;
  1840.         $product $item->getProduct();
  1841.         $purchase $item->getPurchase();
  1842.         if($purchase) {
  1843.             $user $purchase->getUser();
  1844.             if($product && $user) {
  1845.                 if($user->getUserMetaValueByKey("has_payment_info")) {
  1846.                     
  1847.                     $new_purchase = new Purchase();
  1848.                     
  1849.                     $newItem = new PurchaseItem();
  1850.                     
  1851.                     $newItem->setProduct($item->getProduct());
  1852.                     $newItem->setType($item->getType());
  1853.                     $newItem->setPurchase($new_purchase);
  1854.                     
  1855.                     $new_purchase->setStatus(Purchase::STATUS_FAILED); //default to failed (we don't ever want it 'active')
  1856.                     $new_purchase->setCurrentItem($newItem);
  1857.                     $new_purchase->setUser($user);
  1858.                     $new_purchase->setDiscount(0);
  1859.                     
  1860.                     //apply any coupons
  1861.                     $old_coupons $purchase->getCoupons();
  1862.                     foreach($old_coupons as $coupon) {
  1863.                         if($coupon->getProductType() == $product->getType()
  1864.                             && ($coupon->getRecurringType() == Coupon::RECURRING_UNLIMITED
  1865.                             || ($coupon->getRecurringType() == Coupon::RECURRING_SET_MONTHS && $coupon->getMonthsRecurring() > $item->getMonthsRenewed()))
  1866.                         ) {
  1867.                             $new_purchase->addCoupon($coupon);
  1868.                         }
  1869.                     }
  1870.                     
  1871.                     //renew the purchase item
  1872.                     $result $orderHelper->placeOrder(
  1873.                         $user->getUserMetaValueByKey("payment_first_name"),
  1874.                         $user->getUserMetaValueByKey("payment_last_name"),
  1875.                         $user->getUserMetaValueByKey("payment_company"),
  1876.                         $user->getUserMetaValueByKey("payment_address_line_1"),
  1877.                         $user->getUserMetaValueByKey("payment_address_line_2"),
  1878.                         $user->getUserMetaValueByKey("payment_city"),
  1879.                         $user->getUserMetaValueByKey("payment_state_province"),
  1880.                         $user->getUserMetaValueByKey("payment_postal_code"),
  1881.                         $user->getUserMetaValueByKey("payment_country"),
  1882.                         $user->getUserMetaValueByKey("payment_email"),
  1883.                         $user->getUserMetaValueByKey("payment_phone"),
  1884.                         ""//$_SERVER["REMOTE_ADDR"],
  1885.                         $new_purchase->getInvoiceNumber(),
  1886.                         $new_purchase->getTotalUsd(true),
  1887.                         $new_purchase->getTaxUsd(true),
  1888.                         ""//no card number
  1889.                         ""//no expiration date
  1890.                         ""//$user->getUserMetaValueByKey("payment_cvv2"),
  1891.                         false,
  1892.                         $user->getUserMetaValueByKey("payment_token")
  1893.                     );
  1894.                     
  1895.                     
  1896.                     $new_purchase->setFirstname($user->getUserMetaValueByKey("payment_first_name"));
  1897.                     $new_purchase->setLastname($user->getUserMetaValueByKey("payment_last_name"));
  1898.                     $new_purchase->setCompany($user->getUserMetaValueByKey("payment_company"));
  1899.                     $new_purchase->setAddressLine1($user->getUserMetaValueByKey("payment_address_line_1"));
  1900.                     $new_purchase->setAddressLine2($user->getUserMetaValueByKey("payment_address_line_2"));
  1901.                     $new_purchase->setCity($user->getUserMetaValueByKey("payment_city"));
  1902.                     $new_purchase->setStateProvince($user->getUserMetaValueByKey("payment_state_province"));
  1903.                     $new_purchase->setPostalCode($user->getUserMetaValueByKey("payment_postal_code"));
  1904.                     $new_purchase->setCountry($user->getUserMetaValueByKey("payment_country"));
  1905.                     $new_purchase->setEmail($user->getUserMetaValueByKey("payment_email"));
  1906.                     $new_purchase->setPhone($user->getUserMetaValueByKey("payment_phone"));
  1907.                     //$new_purchase->setLast4("");
  1908.                     //$new_purchase->setUserIP($_SERVER["REMOTE_ADDR"]);
  1909.                     //$new_purchase->setUserAgent($_SERVER["HTTP_USER_AGENT"]);
  1910.                     $new_purchase->setRawResponse(json_encode([
  1911.                         "body" => $result["raw"],
  1912.                         "request" => $result["request"],
  1913.                     ]));
  1914.                     
  1915.                     $purchaseNote = new PurchaseNote();
  1916.                     $purchaseNote->setAuthorName("RCS Payment Gateway");
  1917.                     $purchaseNote->setAuthorEmail("admin@rooferscoffeeshop.com");
  1918.                     if($result["result"] == "DECLINED 82") {
  1919.                         $result["result"] = "INVALID CAM\CVV";
  1920.                     }
  1921.                     
  1922.                     if (/*true || */$result["result"] == "APPROVAL" || $result["result"] == "APPROVED") {
  1923.                         
  1924.                         $purchaseNote->setDescription("Automatic payment attempt was successful. Response Code: {$result["code"]}. Response Message: {$result["result"]}");
  1925.                         $purchaseNote->setHiddenDescription(json_encode($result));
  1926.                         $new_purchase->addPurchaseNote($purchaseNote);
  1927.                         
  1928.                         // mark purchase items as processed...
  1929.                         $new_purchase->setStatus(Purchase::STATUS_PROCESSED); //< this updates all expiration dates based on product purchased...
  1930.                         
  1931.                         if($product->getPaymentRate() == Product::RENEW_YEARLY) {
  1932.                             $newItem->setMonthsRenewed($item->getMonthsRenewed() + 12);
  1933.                         }
  1934.                         else {
  1935.                             $newItem->setMonthsRenewed($item->getMonthsRenewed() + 1);
  1936.                         }
  1937.                         
  1938.                         $purchase_completed true;
  1939.                     }else{
  1940.                         $purchaseNote->setDescription("An error occurred while attempting to renew your purchase. Response Code: {$result["code"]}. Response Message: {$result["result"]}");
  1941.                         $purchaseNote->setHiddenDescription(json_encode($result));
  1942.                         $new_purchase->addPurchaseNote($purchaseNote);
  1943.                         
  1944.                         // mark purchase items as failed...
  1945.                         $new_purchase->setStatus(Purchase::STATUS_FAILED); //< this updates all expiration dates based on product purchased...
  1946.                     }
  1947.                     
  1948.                     $entityManager->persist($new_purchase);
  1949.                     $entityManager->flush();
  1950.                     
  1951.                 } 
  1952.                 else{
  1953.                     $purchaseNote = new PurchaseNote();
  1954.                     $purchaseNote->setAuthorName("RCS Payment Gateway");
  1955.                     $purchaseNote->setAuthorEmail("admin@rooferscoffeeshop.com");
  1956.                     $purchaseNote->setDescription("No Payment Information On Record.");
  1957.                     $purchase->addPurchaseNote($purchaseNote);
  1958.                     $purchase->setStatus(Purchase::STATUS_FAILED);
  1959.                 }
  1960.             }
  1961.         }
  1962.         
  1963.         if($purchase_completed) {
  1964.             //send purchase email
  1965.             $message = [];
  1966.             $message[] = ["p" => "Your R-Club membership has been successfully renewed for {$new_purchase->getTotalUsd()}."];
  1967.             $message[] = ["a" => ["href" => "rooferscoffeeshop.com/account""text" => "Go to your account page to update your membership settings at any time."]];
  1968.             
  1969.             $this->addFlash("success""Payment successful. Membership has been re-activated and will now automatically renew.");
  1970.             return $this->redirectToRoute("admin-account-membership", [
  1971.                 "id" => $user_id,
  1972.             ]);
  1973.         }
  1974.         else {
  1975.             
  1976.             $user->setMember(0);
  1977.             $entityManager->persist($user);
  1978.             $entityManager->flush();
  1979.             
  1980.             $this->addFlash("danger""An error occurred when attempting to renew this user's membership. Response Code: {$result["code"]}. Response Message: {$result["result"]}");
  1981.             return $this->redirectToRoute("admin-account-membership", [
  1982.                 "id" => $user_id,
  1983.             ]);
  1984.         }
  1985.         
  1986.     
  1987.         
  1988.         
  1989.         
  1990.     }
  1991.     /**
  1992.      * @Route("/admin-account/membership", methods={"POST"}, name="post-admin-account-membership")
  1993.      */
  1994.     public function adminUpdateAccountMembership (
  1995.         Request $request,
  1996.         UserHelper $userHelper,
  1997.         OrderHelper $orderHelper
  1998.     ) {
  1999.         //Admin check
  2000.         $access false;
  2001.         if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  2002.             $admin $this->getUser();
  2003.             if($admin) {
  2004.                 if($admin->isAdmin()) {
  2005.                     $access true;
  2006.                 }
  2007.             }
  2008.         }
  2009.         
  2010.         if(!$access) {
  2011.             $this->addFlash("warning""This page is only accessible to site administrators.");
  2012.             return $this->redirectToRoute("/");
  2013.         }
  2014.         
  2015.         $user_id $request->get("user_id");
  2016.         $user $userHelper->getUserById($user_id);
  2017.         
  2018.         $payment $request->get("payment");
  2019.         $card $request->get("card");
  2020.         
  2021.         //expiration date
  2022.         $card["card_expires"] = $card["card_expires_month"].$card["card_expires_year"];
  2023.         
  2024.         if (!$payment || !isset($payment["terms"])) {
  2025.             $this->addFlash("warning""You must accept the terms and conditions.");
  2026.             return $this->redirectToRoute("admin-account-membership", [
  2027.                 "id" => $user_id,
  2028.              ]);
  2029.         }
  2030.         
  2031.         $result $orderHelper->generateToken(
  2032.            $payment["firstname"],
  2033.            $payment["lastname"],
  2034.            $payment["company"],
  2035.            $payment["address1"],
  2036.            $payment["address2"],
  2037.            $payment["city"],
  2038.            $payment["state"],
  2039.            $payment["zip"],
  2040.            $payment["country"],
  2041.            $payment["email"],
  2042.            $payment["phone"],
  2043.            $_SERVER["REMOTE_ADDR"],
  2044.            $card["card_number"],
  2045.            $card["card_expires"],
  2046.            $card["card_csc"]
  2047.         );
  2048.         
  2049.         if ($result["result"] == "APPROVAL" || $result["result"] == "APPROVED") {
  2050.             
  2051.             $last4 $card["card_number"];
  2052.             $last4 preg_replace("/[^0-9]/"''$last4);
  2053.             $last4 substr($last4, -4);
  2054.             
  2055.             $user->setUsermetum("has_payment_info""1");
  2056.             $user->setUsermetum("payment_first_name"$payment["firstname"]);
  2057.             $user->setUsermetum("payment_last_name"$payment["lastname"]);
  2058.             $user->setUsermetum("payment_company"$payment["company"]);
  2059.             $user->setUsermetum("payment_address_line_1"$payment["address1"]);
  2060.             $user->setUsermetum("payment_address_line_2"$payment["address2"]);
  2061.             $user->setUsermetum("payment_city"$payment["city"]);
  2062.             $user->setUsermetum("payment_state_province"$payment["state"]);
  2063.             $user->setUsermetum("payment_postal_code"$payment["zip"]);
  2064.             $user->setUsermetum("payment_country"$payment["country"]);
  2065.             $user->setUsermetum("payment_email"$payment["email"]);
  2066.             $user->setUsermetum("payment_phone"$payment["phone"]);
  2067.             $user->setUsermetum("payment_last4"$last4);
  2068.             $user->setUsermetum("payment_exp"$card["card_expires"]);
  2069.             //$user->setUsermetum("payment_cvv2", $card["card_csc"]);
  2070.             $user->setUsermetum("payment_token"$result["token"]);
  2071.             $user->setUsermetum("payment_token_response"$result["token_response"]);
  2072.             
  2073.             $manager $this->getDoctrine()->getManager();
  2074.             $manager->persist($user);
  2075.             $manager->flush();
  2076.             
  2077.             $this->addFlash("success""Membership settings updated.");
  2078.             return $this->redirectToRoute("admin-account-membership", [
  2079.                 "id" => $user_id,
  2080.              ]);
  2081.         }
  2082.         else {
  2083.             $this->addFlash("warning""Their was an error while updating your payment information. Response: {$result["result"]}");
  2084.             return $this->redirectToRoute("admin-account-membership", [
  2085.                 "id" => $user_id,
  2086.              ]);
  2087.         }
  2088.         
  2089.         
  2090.         
  2091.     }
  2092.     
  2093. }