src/Controller/BigCommerceController.php line 21

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Utils\BigCommerceConfig;
  4. use Guzzle\Http\Client;
  5. use Psr\Log\LoggerInterface;
  6. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  7. use Symfony\Component\HttpFoundation\Cookie;
  8. use Symfony\Component\HttpFoundation\Request;
  9. use Symfony\Component\HttpFoundation\Response;
  10. class BigCommerceController extends AbstractController
  11. {
  12.     private $logger;
  13.     public function __construct(LoggerInterface $devdebugLogger) {
  14.         $this->logger $devdebugLogger;
  15.     }
  16.     
  17.     public function load(Request $requestBigCommerceConfig $config)
  18.     {
  19.         // ensure app has minimum configuration
  20.         $client_id $config->getClientId();
  21.         if(empty($client_id)) {
  22.             return $this->render('/bigcommerce/error.html.twig', array(
  23.                 'message' => "Missing CLIENT_ID in .env"
  24.             ));
  25.         }
  26.         $client_secret $config->getClientSecret();
  27.         if(empty($client_secret)) {
  28.             return $this->render('/bigcommerce/error.html.twig', array(
  29.                 'message' => "Missing CLIENT_SECRET in .env"
  30.             ));
  31.         }
  32.         // Ensure request is from BigCommerce environment, or store hash is known in cookie
  33.         $cookie_store_hash $config->getStoreHash();
  34.         $signed_payload $request->query->get('signed_payload');
  35.         if(empty($signed_payload)) {
  36.             $this->logger->debug('Invalid to request outside of BigCommerce.');
  37.             return $this->render('/bigcommerce/error.html.twig', array(
  38.                 'message' => "Invalid to request outside of BigCommerce"
  39.             ));
  40.         }
  41.         $data $this->verifySignedRequest($signed_payload$client_secret);
  42.         if (empty($data)) {
  43.             $this->logger->debug('Invalid signed_payload.');
  44.             return $this->render('/bigcommerce/error.html.twig', array(
  45.                 'message' => "Invalid signed_payload. Is request from BigCommerce?"
  46.             ));
  47.         }
  48.         // Don't load the app if not configured completely
  49.         $store_hash $data['store_hash'];
  50.         if(!$config->hasAuthToken($store_hash)) {
  51.             return $this->render('/bigcommerce/error.html.twig', array(
  52.                 'message' => "BigCommerce application is not configured completely"
  53.             ));
  54.         }
  55.         // Populate the data for the view
  56.         $user_email $data['user']['email'];
  57.         $welcome_name $this->getWelcomeName($user_email$config);
  58.         $view = array(
  59.             "welcome_name" => $welcome_name
  60.         );
  61.         // Render view, and attach critical elements for user-application context
  62.         $response $this->render('/bigcommerce/load.html.twig'$view);
  63.         // ! Save the storehash for future loads
  64.         $response->headers->setCookie(new Cookie('storehash'$store_hash));
  65.        $response->headers->setCookie(new Cookie('user-email'$user_email));
  66.         return $response;
  67.     }
  68.         /**
  69.      * Primary Index Page after App is loaded in BigCommerce
  70.      *
  71.      * @param Request $request
  72.      * @param BigCommerceConfig $config
  73.      * @return Response
  74.      */
  75.     public function home(Request $requestBigCommerceConfig $config)
  76.     {
  77.         // Get the current user's email
  78.         $user_email '';
  79.         $user_email $request->cookies->get('user-email');
  80.         $welcome_name $this->getWelcomeName($user_email$config);
  81.         $view = array(
  82.             "welcome_name" => $welcome_name
  83.         );
  84.         $cookies $request->cookies;
  85.         $cookies->has('storehash') ? $hash $cookies->get('storehash') : $hash null;
  86.         if($hash !== null && $hash === $config->getStoreHash()) {
  87.             $response $this->render('/bigcommerce/load.html.twig'$view);
  88.         } else {
  89.             $this->logger->debug('Invalid to request outside of BigCommerce for /home.');
  90.             $response $this->render('/bigcommerce/error.html.twig', array(
  91.                 'message' => "Invalid to request outside of BigCommerce"
  92.             ));
  93.         }
  94.         // $response = $this->render('/bigcommerce/load.html.twig', $view);
  95.         return $response;
  96.     }
  97.     private function getWelcomeName($user_emailBigCommerceConfig $config) {
  98.         // Find a Customer record using the email
  99.         // TODO: use the BigCommerce API client
  100.         $api_url $config->get_api_url();
  101.         $api_url $api_url.'/v2/customers?email='.urlencode($user_email);
  102.         $data_string "";
  103.         $customrequest "GET";
  104.         $welcome_name $user_email ?: "John Doe";
  105.         $customer $config->curl($api_url$data_string$customrequest);
  106.         if(count($customer) > 0)
  107.         {
  108.             $first_name $customer[0]['first_name'];
  109.             $last_name $customer[0]['last_name'];
  110.             $welcome_name $first_name " " $last_name;
  111.         }
  112.         return $welcome_name;
  113.     }    
  114.     /**
  115.      * BigCommerce application install app auth
  116.      *
  117.      * @param Request $request
  118.      * @param BigCommerceConfig $config
  119.      * @return void
  120.      */
  121.     public function auth(Request $requestBigCommerceConfig $config)
  122.     {
  123.         $code $request->query->get('code');
  124.         $scope $request->query->get('scope');
  125.         $context $request->query->get('context');
  126.         if(empty($code)) {
  127.             $this->logger->warning('Missing code.');
  128.             return $this->render('/bigcommerce/error.html.twig', array(
  129.                 'message' => "Missing code"
  130.             ));
  131.         }
  132.         if(empty($scope)) {
  133.             $this->logger->warning('Missing scope.');
  134.             return $this->render('/bigcommerce/error.html.twig', array(
  135.                 'message' => "Missing scope"
  136.             ));
  137.         }
  138.         if(empty($code)) {
  139.             $this->logger->warning('Missing context.');
  140.             return $this->render('/bigcommerce/error.html.twig', array(
  141.                 'message' => "Missing context"
  142.             ));
  143.         }
  144.         $payload = array(
  145.             'client_id' => $config->getClientId(),
  146.             'client_secret' => $config->getClientSecret(),
  147.             'redirect_uri' => $config->getRedirectUri(),
  148.             'grant_type' => 'authorization_code',
  149.             'code' => $code,
  150.             'scope' => $scope,
  151.             'context' => $context
  152.         );
  153.         $client = new Client(getenv('BC_AUTH_SERVICE'));
  154.         $req $client->post('/oauth2/token', array(), $payload, array(
  155.             'exceptions' => false
  156.         ));
  157.         $resp $req->send();
  158.         if ($resp->getStatusCode() == 200) {
  159.             $data $resp->json();
  160.             list($context$storehash) = explode('/'$data['context'], 2);
  161.             $config->set_app_detail($storehash$data['access_token']);
  162.             $view = array(
  163.                 "email" => $data['user']['email']
  164.             );
  165.             return $this->render('/bigcommerce/load.html.twig'$view);
  166.         } else {
  167.             $this->logger->warning('Something went wrong... [' $resp->getStatusCode() . '] ' $resp->getBody());
  168.             $view = array("error" => 'Something went wrong... [' $resp->getStatusCode() . '] ' $resp->getBody());
  169.             return $this->render('error.html.twig'$view);
  170.         }
  171.     }
  172.     /*
  173.      *  BigCommerce application install app auth
  174.      */
  175.     public function remove_user(Request $request)
  176.     {
  177.         $client_secret=$_ENV['CLIENT_SECRET'];
  178.         $data $this->verifySignedRequest($request->query->get('signed_payload'), $client_secret$logger);
  179.         if (empty($data)) {
  180.             $this->logger->warning('Invalid signed_payload.');
  181.             return 'Invalid signed_payload.';
  182.         }
  183.         return '[Remove User] ' $data['user']['email'];
  184.     }
  185.     function verifySignedRequest($signedRequest$client_secret)
  186.     {
  187.         list($encodedData$encodedSignature) = explode('.'$signedRequest2);
  188.         // decode the data
  189.         $signature base64_decode($encodedSignature);
  190.         $jsonStr base64_decode($encodedData);
  191.         $data json_decode($jsonStrtrue);
  192.         // confirm the signature
  193.         $expectedSignature hash_hmac('sha256'$jsonStr$client_secret$raw false);
  194.         if (!hash_equals($expectedSignature$signature)) {
  195.             $this->logger->warning('Bad signed request from BigCommerce!');
  196.             return null;
  197.         }
  198.         return $data;
  199.     }
  200.     /**
  201.     * Configure the static BigCommerce API client with the authorized app's auth token, the client ID from the environment
  202.      * and the store's hash as provided.
  203.      * @param string $storeHash Store hash to point the BigCommece API to for outgoing requests.
  204.      */
  205.     function configureBCApi($storeHash)
  206.     {
  207.         Bigcommerce::configure(array(
  208.             'client_id' => clientId(),
  209.             'auth_token' => getAuthToken($storeHash),
  210.             'store_hash' => $storeHash
  211.         ));
  212.     }
  213.     /**
  214.      * @return string Get the app's client ID from the environment vars
  215.      */
  216.     function clientId()
  217.     {
  218.         $clientId getenv('CLIENT_ID');
  219.         return $clientId ?: '';
  220.     }
  221.     /**
  222.      * @return string Get the app's client secret from the environment vars
  223.      */
  224.     function clientSecret()
  225.     {
  226.         $clientSecret getenv('CLIENT_SECRET');
  227.         return $clientSecret ?: '';
  228.     }
  229.     /**
  230.      * @return string Get auth service URL from the environment vars
  231.      */
  232.     function bcAuthService()
  233.     {
  234.         $bcAuthService getenv('BC_AUTH_SERVICE');
  235.         return $bcAuthService ?: '';
  236.     }
  237.     /**
  238.      * @return string Get the callback URL from the environment vars
  239.      */
  240.     function callbackUrl()
  241.     {
  242.         $callbackUrl getenv('CALLBACK_URL');
  243.         return $callbackUrl ?: '';
  244.     }
  245. }