/**
  * @return Location[]
  */
 public function getParsedLocationsFromLinkedIn()
 {
     $channel = $this->channelWizard->getChannel();
     $profile = $this->channelWizard->get('profile');
     $locations = [];
     $locationName = $profile->displayName;
     if (!empty($profile->username)) {
         $locationName .= ' (' . $profile->username . ')';
     }
     // Get the location module for the user stream.
     $locationModuleUser = $this->locationService->getLocationModule('campaignchain/location-linkedin', 'campaignchain-linkedin-user');
     // Create the location instance for the user stream.
     $locationUser = new Location();
     $locationUser->setIdentifier($profile->identifier);
     $locationUser->setName($locationName);
     $locationUser->setLocationModule($locationModuleUser);
     if (!$profile->photoURL || strlen($profile->photoURL) == 0) {
         $locationUser->setImage($this->assetsHelper->getUrl('/bundles/campaignchainchannellinkedin/ghost_person.png'));
     } else {
         $locationUser->setImage($profile->photoURL);
     }
     $locationUser->setChannel($channel);
     $locationModuleUser->addLocation($locationUser);
     $locations[$profile->identifier] = $locationUser;
     $tokens = $this->channelWizard->get('tokens');
     /** @var Token $userToken */
     $userToken = array_values($tokens)[0];
     $connection = $this->client->getConnectionByToken($userToken);
     $companies = $connection->getCompanies();
     //there is only a user page
     if (empty($companies)) {
         return $locations;
     }
     // Get the location module for the page stream.
     $locationModulePage = $this->locationService->getLocationModule('campaignchain/location-linkedin', 'campaignchain-linkedin-page');
     $wizardPages = [];
     foreach ($companies as $company) {
         $newToken = new Token();
         $newToken->setAccessToken($userToken->getAccessToken());
         $newToken->setApplication($userToken->getApplication());
         $newToken->setTokenSecret($userToken->getTokenSecret());
         $tokens[$company['id']] = $newToken;
         $this->channelWizard->set('tokens', $tokens);
         $companyData = $connection->getCompanyProfile($company['id']);
         $locationPage = new Location();
         $locationPage->setChannel($channel);
         $locationPage->setName($companyData['name']);
         $locationPage->setIdentifier($companyData['id']);
         if (isset($companyData['squareLogoUrl'])) {
             $locationPage->setImage($companyData['squareLogoUrl']);
         } else {
             $locationPage->setImage($this->assetsHelper->getUrl('/bundles/campaignchainchannellinkedin/ghost_person.png'));
         }
         $locationPage->setLocationModule($locationModulePage);
         $locationModulePage->addLocation($locationPage);
         $locations[$companyData['id']] = $locationPage;
         $wizardPages[$companyData['id']] = $companyData;
     }
     $this->channelWizard->set('pagesData', $wizardPages);
     return $locations;
 }
Example #2
0
 /**
  * Finds a Location by the URL and automatically creates the Location if it
  * does not exist and if the respective Location module supports auto
  * generation of Locations.
  **
  * @param $url
  * @param $operation Operation
  * @return bool|Location|null|object
  */
 public function findLocationByUrl($url, $operation, $alias = null)
 {
     $url = ParserUtil::sanitizeUrl($url);
     /*
      * If not a Location, then see if the URL is inside a connected
      * Channel's top-level Locations. To do so, check if one of these
      * criteria apply:
      * - The Location URL matches the beginning of the CTA URL
      * - The Location identifier is included in the CTA URL as well
      *   as the domain
      */
     if (ParserUtil::urlExists($url)) {
         $urlParts = parse_url($url);
         if ($urlParts['scheme'] == 'http') {
             $urlAltScheme = str_replace('http://', 'https://', $url);
         } elseif ($urlParts['scheme'] == 'https') {
             $urlAltScheme = str_replace('https://', 'http://', $url);
         }
         $repository = $this->em->getRepository('CampaignChainCoreBundle:Location');
         $query = $repository->createQueryBuilder('location')->where("(:url LIKE CONCAT('%', location.url, '%')) OR " . "(:url_alt_scheme LIKE CONCAT('%', location.url, '%')) OR " . "(" . "location.identifier IS NOT NULL AND " . ":url LIKE CONCAT('%', location.identifier, '%') AND " . "location.url LIKE :host" . ")")->andWhere('location.parent IS NULL')->setParameter('url', $url)->setParameter('url_alt_scheme', $urlAltScheme)->setParameter('host', $urlParts['host'] . '%')->getQuery();
         /** @var Location $matchingLocation */
         $matchingLocation = $query->getOneOrNullResult();
         if ($matchingLocation) {
             /*
              * Create a new Location based on the tracking alias
              * within the matching Location's Channel.
              *
              * If no tracking alias was provided, we take the
              * default LocationModule to create a new Location.
              */
             if (!$alias) {
                 // Done if the URL is exactly the same in the matching Location.
                 if ($matchingLocation->getUrl() == $url || $matchingLocation->getUrl() == $urlAltScheme) {
                     return $matchingLocation;
                 }
                 // Let's move on to create a new Location with the default module.
                 $locationService = $this->container->get('campaignchain.core.location');
                 /** @var LocationModule $locationModule */
                 $locationModule = $locationService->getLocationModule(self::DEFAULT_LOCATION_BUNDLE_NAME, self::DEFAULT_LOCATION_MODULE_IDENTIFIER);
                 if (!$locationModule) {
                     throw new \Exception('No Location module found for bundle "' . $matchingLocation->getChannel()->getBundle()->getName() . ' and module ' . $matchingLocation->getChannel()->getChannelModule()->getIdentifier() . '"');
                 }
             } else {
                 /*
                  * Get the Location module within the matching Location's
                  * Channel and with the given tracking alias.
                  */
                 /** @var LocationModule $locationModule */
                 $locationModule = $this->getLocationModuleByTrackingAlias($matchingLocation->getChannel()->getChannelModule(), $alias);
                 // Done if the matching Location also matches the alias and URL.
                 if ($matchingLocation->getLocationModule() == $locationModule && ($matchingLocation->getUrl() == $url || $matchingLocation->getUrl() == $urlAltScheme)) {
                     return $matchingLocation;
                 }
                 /*
                  * See if there is already another Location that matches the
                  * aliase's Location module and the URL.
                  */
                 $repository = $this->em->getRepository('CampaignChainCoreBundle:Location');
                 $query = $repository->createQueryBuilder('location')->where('location.locationModule = :locationModule')->andWhere('(location.url = :url OR location.url = :url_alt_scheme')->setParameter('locationModule', $locationModule)->setParameter('url', $url)->setParameter('url_alt_scheme', $urlAltScheme)->getQuery();
                 /** @var Location $location */
                 $location = $query->getOneOrNullResult();
                 // We found an existing Location, we're done.
                 if ($location) {
                     return $location;
                 }
                 if (!$locationModule) {
                     throw new \Exception('Cannot map tracking alias "' . $alias . '" to a "' . 'Location module that belongs to Channel module "' . $matchingLocation->getChannel()->getBundle()->getName() . '/' . $matchingLocation->getChannel()->getChannelModule()->getIdentifier() . '"');
                 }
             }
             /*
              * If the matching Location provides auto-generation of Locations,
              * then let's create a new child Location.
              */
             $ctaServiceName = $locationModule->getServices()['job_cta'];
             if ($ctaServiceName) {
                 // Create the new Location
                 $location = new Location();
                 $location->setUrl($url);
                 $location->setOperation($operation);
                 $location->setChannel($matchingLocation->getChannel());
                 $location->setParent($matchingLocation);
                 // Update the Location module to be the current
                 // one.
                 $location->setLocationModule($locationModule);
                 // Let the module's service process the new
                 // Location.
                 $ctaService = $this->container->get($ctaServiceName);
                 return $ctaService->execute($location);
             } else {
                 throw new \Exception('No CTA Job service defined for Location module ' . 'of bundle "' . $locationModule->getBundle()->getName() . '" ' . 'and module "' . $locationModule->getIdentifier() . '"');
             }
         } else {
             return false;
         }
     }
     throw new \Exception('The URL ' . $url . ' does not exist.');
 }
 public function addLocationAction(Request $request)
 {
     $wizard = $this->get('campaignchain.core.channel.wizard');
     $channel = $wizard->getChannel();
     $profile = $wizard->get('profile');
     $locations = [];
     $locationName = $profile->displayName;
     $username = $profile->username;
     if (!empty($username)) {
         $locationName .= ' (' . $username . ')';
     }
     // Get the location module for the user stream.
     $locationService = $this->get('campaignchain.core.location');
     $locationModuleUser = $locationService->getLocationModule('campaignchain/location-facebook', 'campaignchain-facebook-user');
     // Create the location instance for the user stream.
     $locationUser = new Location();
     $locationUser->setChannel($channel);
     $locationUser->setName($locationName);
     $locationUser->setIdentifier($profile->identifier);
     $locationUser->setImage($profile->photoURL);
     $locationUser->setLocationModule($locationModuleUser);
     $locationModuleUser->addLocation($locationUser);
     $locations[$profile->identifier] = $locationUser;
     // Connect to Facebook to retrieve pages related to the user.
     $tokens = $wizard->get('tokens');
     $client = $this->container->get('campaignchain.channel.facebook.rest.client');
     $connection = $client->connect($tokens[$profile->identifier]->getAccessToken());
     if ($connection) {
         // TODO: Check whether user has manage_pages permission with /me/permissions
         // check if the user owns Facebook pages
         $response = $connection->api('/me/accounts');
         $pagesData = $response['data'];
         if (is_array($pagesData) && count($pagesData)) {
             // TODO: Should we check whether the Facebook page has actually been published (through is_published), because if not, then posting to it won't make sense? Same with can_post and perms from /me/accounts?
             // Get the location module for the page stream.
             $locationModulePage = $locationService->getLocationModule('campaignchain/location-facebook', 'campaignchain-facebook-page');
             // User owns pages, so let's build the form and ask him whether to create channels for each of them
             // with the respective channel name
             foreach ($pagesData as $pageData) {
                 // Save the token in the Wizard.
                 $tokens = $wizard->get('tokens');
                 $newToken = new Token();
                 $newToken->setAccessToken($pageData['access_token']);
                 $application = $tokens[$wizard->get('facebook_user_id')]->getApplication();
                 $newToken->setApplication($application);
                 $tokens[$pageData['id']] = $newToken;
                 $wizard->set('tokens', $tokens);
                 // Get the page picture
                 $pageConnection = $client->connect($pageData['access_token']);
                 $pagePicture = $pageConnection->api('/' . $pageData['id'] . '/picture', 'GET', ['redirect' => false, 'type' => 'large']);
                 $pageData['picture_url'] = $pagePicture['data']['url'];
                 // Create the location instance for the page stream.
                 $locationPage = new Location();
                 $locationPage->setChannel($channel);
                 $locationPage->setName($pageData['name']);
                 $locationPage->setIdentifier($pageData['id']);
                 $locationPage->setImage($pageData['picture_url']);
                 $locationPage->setLocationModule($locationModulePage);
                 $locationModulePage->addLocation($locationPage);
                 $locations[$pageData['id']] = $locationPage;
                 $wizardPages[$pageData['id']] = $pageData;
             }
             $wizard->set('pagesData', $wizardPages);
         }
     }
     $data = [];
     $form = $this->createFormBuilder($data);
     foreach ($locations as $identifier => $location) {
         // Has the page already been added as a location?
         $repository = $this->getDoctrine()->getRepository('CampaignChainCoreBundle:Location');
         $pageExists = $repository->findOneBy(['identifier' => $identifier, 'locationModule' => $location->getLocationModule()]);
         // Compose the checkbox form field.
         $form->add($identifier, CheckboxType::class, ['label' => '<img class="campaignchain-location-image-input-prepend" src="' . $location->getImage() . '"> ' . $location->getName(), 'required' => false, 'data' => true, 'mapped' => false, 'disabled' => $pageExists, 'attr' => ['align_with_widget' => true]]);
         // If a location has already been added before, remove it from this process.
         // TODO: Also assign existing locations to the new FB user.
         if ($pageExists) {
             unset($locations[$identifier]);
         }
     }
     $form = $form->getForm();
     $form->handleRequest($request);
     if ($form->isValid()) {
         // Find out which locations should be added, i.e. which respective checkbox is active.
         foreach ($locations as $identifier => $location) {
             if (!$form->get($identifier)->getData()) {
                 unset($locations[$identifier]);
                 $wizard->removeLocation($identifier);
             }
         }
         // If there's at least one location to be added, then have the user configure it.
         if (is_array($locations) && count($locations)) {
             $wizard->setLocations($locations);
             return $this->redirectToRoute('campaignchain_channel_facebook_location_configure', ['step' => 0]);
         } else {
             $this->addFlash('warning', 'No new location has been added.');
             return $this->redirectToRoute('campaignchain_core_location');
         }
     }
     return $this->render('CampaignChainCoreBundle:Base:new.html.twig', ['page_title' => 'Add Facebook Locations', 'form' => $form->createView()]);
 }