public function indexAction(Request $request)
 {
     // get applications configuration list
     $apps = $this->container->getParameter('dream_commerce_shop_appstore.apps');
     $validator = new RequestValidator($request);
     try {
         // validate application settings
         $appName = $validator->getApplicationName($apps);
         $validator->setApplication($apps[$appName]);
         $params = $validator->validateAppstoreRequest();
     } catch (InvalidRequestException $ex) {
         throw new BadRequestHttpException($ex->getMessage());
     }
     /**
      * @var $eventDispatcher EventDispatcher
      */
     $eventDispatcher = $this->get('event_dispatcher');
     // dispatch appstore action
     switch ($params['action']) {
         case 'install':
             $event = new InstallEvent($appName, $apps[$appName], $params);
             $eventDispatcher->dispatch(DreamCommerceShopAppstoreEvents::APPLICATION_INSTALLED, $event);
             break;
         case 'billing_install':
             $event = new BillingInstallEvent($appName, $apps[$appName], $params);
             $eventDispatcher->dispatch(DreamCommerceShopAppstoreEvents::APPLICATION_PAID, $event);
             break;
         case 'billing_subscription':
             $event = new SubscriptionEvent($appName, $apps[$appName], $params);
             $eventDispatcher->dispatch(DreamCommerceShopAppstoreEvents::APPLICATION_SUBSCRIPTION, $event);
             break;
         case 'uninstall':
             $event = new UninstallEvent($appName, $params);
             $eventDispatcher->dispatch(DreamCommerceShopAppstoreEvents::APPLICATION_UNINSTALLED, $event);
             break;
         case 'upgrade':
             $event = new UpgradeEvent($appName, $apps[$appName], $params);
             $eventDispatcher->dispatch(DreamCommerceShopAppstoreEvents::APPLICATION_UPGRADED, $event);
             break;
         default:
             throw new \HttpInvalidParamException('Unsupported action');
     }
     return new Response();
 }
 /**
  * @param FilterControllerEvent $event
  * @throws HttpException
  */
 public function onKernelController(FilterControllerEvent $event)
 {
     // last event used before token invalid exception is thrown
     $this->lastEvent = $event;
     /**
      * @var $controller ApplicationControllerInterface
      */
     $controller = $event->getController();
     /*
      * $controller passed can be either a class or a Closure.
      * This is not usual in Symfony but it may happen.
      * If it is a class, it comes in array format
      */
     if (!is_array($controller)) {
         return;
     }
     // if latest controller on stack is a filtered instance
     if ($controller[0] instanceof ApplicationControllerInterface) {
         // get current request data
         $request = $event->getRequest();
         $requestValidator = new RequestValidator($request);
         try {
             // get parameters
             $appName = $requestValidator->getApplicationName($this->applications);
             $appData = $this->applications[$appName];
             $requestValidator->setApplication($appData);
             $params = $requestValidator->validateAppRequest();
         } catch (InvalidRequestException $ex) {
             // if request is malformed
             throw new BadRequestHttpException('Invalid request');
         }
         // handle shop arguments on iframe (eg. product list checkboxes)
         if ($request->query->has('id')) {
             $ids = $request->query->get('id');
             $idsList = @json_decode($ids);
             $request->query->set('id', $idsList);
         }
         // search for installed shop instance by app
         /**
          * @var $repo ShopRepositoryInterface
          */
         $repo = $this->objectManager->getRepository('DreamCommerce\\ShopAppstoreBundle\\Model\\ShopInterface');
         $shop = $repo->findOneByNameAndApplication($params['shop'], $appName);
         // not installed - throw an error
         if (!$shop) {
             $this->redirect($event, 'not_installed');
         }
         // verify version requirements
         if ($appData['minimal_version'] > 0) {
             if ($shop->getVersion() < $appData['minimal_version']) {
                 $this->redirect($event, 'upgrade');
             }
         }
         // if an application controller needs to be paid
         if ($controller[0] instanceof PaidControllerInterface) {
             $billing = $shop->getBilling();
             if (empty($billing)) {
                 $this->redirect($event, 'unpaid');
             }
         }
         // need a subscription?
         if ($controller[0] instanceof SubscribedControllerInterface) {
             $subscriptions = $shop->getSubscriptions();
             if (!count($subscriptions)) {
                 $this->redirect($event, 'unsubscribed');
             }
             $newest = $subscriptions[0];
             $expires = $newest->getExpiresAt();
             if ($expires < new \DateTime()) {
                 $this->redirect($event, 'not_installed');
             }
         }
         // get shop token
         $token = $shop->getToken();
         // instantiate a client
         /**
          * @var $client Client\Bearer
          */
         $client = $this->applicationRegistry->get($appName)->getClient($shop);
         // token expired - attempt to refresh
         if ($token->getExpiresAt()->getTimestamp() - (new \DateTime())->getTimestamp() < 86400) {
             $this->refresher->setClient($client);
             $this->refresher->refresh($shop);
         }
         // set token on client
         $client->setAccessToken($token->getAccessToken());
         // action performed on token is invalid
         $client->setOnTokenInvalidHandler(array($this, 'invalidTokenRedirect'));
         // pass shop and client
         $controller[0]->injectClient($client, $shop);
         // save variables
         $event->getRequest()->attributes->set('_dream_commerce_shop_appstore_client', $client);
         $event->getRequest()->attributes->set('_dream_commerce_shop_appstore_shop', $shop);
     }
 }