public function configureLocationAction(Request $request, $step) { $wizard = $this->get('campaignchain.core.channel.wizard'); $locations = $wizard->getLocations(); // Get the identifier of the first element in the locations array. $identifier = array_keys($locations)[$step]; // Retrieve the current location object. $location = $locations[$identifier]; $locationType = $this->get('campaignchain.core.form.type.location'); $locationType->setBundleName($location->getLocationModule()->getBundle()->getName()); $locationType->setModuleIdentifier($location->getLocationModule()->getIdentifier()); $locationType->setView('hide_url'); $form = $this->createForm($locationType, $location); $form->handleRequest($request); if ($form->isValid()) { // Keep track of Flash Bag Messages in the Wizard. $flashBagMsg = ''; $wizard->set('flashBagMsg', $flashBagMsg); // Is the location a Facebook user or page? The related location module will tell. if ($location->getLocationModule()->getIdentifier() == 'campaignchain-facebook-user') { // The display name of the Facebook user will be the name of the CampaignChain channel. $wizard->setName($location->getName()); // Get the OAuth profile data from the Wizard. $profile = $wizard->get('profile'); // Define the URL of the location $location->setUrl($profile->profileURL); // Here we handle the specific data of the user stream as provided by Facebook. $user = new User(); $user->setLocation($location); $user->setScope($this->applicationInfo['parameters']['scope']); $user->setIdentifier($profile->identifier); $user->setUsername($profile->username); $user->setDisplayName($profile->displayName); $user->setFirstName($profile->firstName); $user->setLastName($profile->lastName); $user->setDescription($profile->description); $user->setGender($profile->gender); $user->setLanguage($profile->language); $user->setAge($profile->age); $user->setEmail($profile->email); $user->setEmailVerified($profile->emailVerified); $user->setPhone($profile->phone); $user->setAddress($profile->address); $user->setCountry($profile->country); $user->setRegion($profile->region); $user->setCity($profile->city); $user->setZip($profile->zip); $user->setWebsiteUrl($profile->webSiteURL); $user->setProfileUrl($profile->profileURL); $user->setProfileImageUrl($profile->photoURL); $obj = new \ReflectionObject($profile); if ($obj->hasProperty('coverInfoUrl')) { $user->setCoverInfoUrl($profile->coverInfoURL); } // Remember the user object in the Wizard. $wizard->set($user->getIdentifier(), $user); $flashBagMsg = $wizard->get('flashBagMsg'); $flashBagMsg .= '<li>User stream: <a href="' . $profile->profileURL . '">' . $profile->displayName . '</a></li>'; $wizard->set('flashBagMsg', $flashBagMsg); } else { $pagesData = $wizard->get('pagesData'); $pageData = $pagesData[$identifier]; // Connect to Facebook to retrieve detailed info about this page. $client = $this->container->get('campaignchain.channel.facebook.rest.client'); $tokens = $wizard->get('tokens'); $connection = $client->connect($tokens[$wizard->get('facebook_user_id')]->getAccessToken()); $fields = ['about', 'link', 'name', 'username', 'description', 'can_post', 'category', 'cover', 'is_published']; $response = $connection->api('/' . $identifier . '?fields=' . implode(',', $fields)); $pageData = array_merge($pageData, $response); // Define the URL of the location $location->setUrl($pageData['link']); $page = new Page(); $page->setLocation($location); // If the user is not in the session, then it has already been // created. if ($wizard->has($wizard->get('facebook_user_id'))) { $user = $wizard->get($wizard->get('facebook_user_id')); $page->addUser($user); } else { $user = $this->getDoctrine()->getRepository('CampaignChainLocationFacebookBundle:User')->findOneByIdentifier($wizard->get('facebook_user_id')); if ($user) { $page->addUser($user); } } $page->setIdentifier($identifier); $page->setName($pageData['name']); if (isset($pageData['username'])) { $page->setUsername($pageData['username']); } if (isset($pageData['description'])) { $page->setDescription($pageData['description']); } if (isset($pageData['about'])) { $page->setAbout($pageData['about']); } $page->setPermissions($pageData['perms']); $page->setCanPost($pageData['can_post']); $page->setCategory($pageData['category']); if (isset($pageData['cover'])) { $page->setCoverId($pageData['cover']['cover_id']); $page->setCoverSource($pageData['cover']['source']); $page->setCoverOffsetX($pageData['cover']['offset_x']); $page->setCoverOffsetY($pageData['cover']['offset_y']); } $page->setIsPublished($pageData['is_published']); $page->setLink($pageData['link']); $page->setPictureUrl($pageData['picture_url']); // Remember the user object in the Wizard. $wizard->set($page->getIdentifier(), $page); $flashBagMsg = $wizard->get('flashBagMsg'); $flashBagMsg .= '<li>Page: <a href="' . $page->getLink() . '">' . $page->getName() . '</a></li>'; $wizard->set('flashBagMsg', $flashBagMsg); } // Add the updated Location to the wizard $wizard->addLocation($identifier, $location); // Are there still locations to be configured? if (isset(array_keys($locations)[$step + 1])) { // Redirect to this same page to configure the next location. return $this->redirectToRoute('campaignchain_channel_facebook_location_configure', ['step' => $step + 1]); } else { // We are done with configuring the locations, so lets end the Wizard and persist the locations. // TODO: Wrap into DB transaction. $em = $this->getDoctrine()->getManager(); foreach ($locations as $identifier => $location) { // Persist the Facebook user- and page-specific data. $em->persist($wizard->get($identifier)); // schedule job to get metrics from now on if ($location->getLocationModule()->getIdentifier() === 'campaignchain-facebook-page') { $this->get('campaignchain.job.report.location.facebook')->schedule($location); } } $this->addFlash('success', 'The following locations are now connected:' . '<ul>' . $wizard->get('flashBagMsg') . '</ul>'); $tokens = $wizard->get('tokens'); $channel = $wizard->persist(); /* * Store all access tokens per location in the OAuth Client * bundle's Token entity, but only for the Facebook user * locations, not the page locations. */ $tokenService = $this->get('campaignchain.security.authentication.client.oauth.token'); foreach ($tokens as $identifier => $token) { if (isset($locations[$identifier])) { $token = $em->merge($token); $token->setLocation($locations[$identifier]); $tokenService->setToken($token); } } $wizard->end(); $em->flush(); return $this->redirectToRoute('campaignchain_core_location'); } } return $this->render('CampaignChainLocationFacebookBundle::new.html.twig', ['page_title' => 'Configure Facebook Location', 'form' => $form->createView(), 'location' => $location]); }