public function execute(Location $location) { // Set HTML title as Location name. $location->setName('Form on ' . ParserUtil::getHTMLTitle($location->getUrl())); // Set the Website page module as the Location module. $locationModule = $this->locationService->getLocationModule('campaignchain/location-website', 'campaignchain-website-form'); $location->setLocationModule($locationModule); // Set the image. $location->setImage($this->assetsHelper->getUrl('bundles/campaignchainlocationwebsite/images/icons/256x256/form.png', null)); return $location; }
public function newAction(Request $request) { $locationType = $this->get('campaignchain.core.form.type.location'); $locationType->setBundleName('campaignchain/location-website'); $locationType->setModuleIdentifier('campaignchain-website'); $form = $this->createFormBuilder()->add('URL', 'url', array('label' => 'Website URL', 'constraints' => array(new Url(array('checkDNS' => true)))))->getForm(); $form->handleRequest($request); if ($form->isValid()) { $locationURL = $form->getData()['URL']; $locationName = ParserUtil::getHTMLTitle($locationURL, $locationURL); $locationService = $this->get('campaignchain.core.location'); $locationModule = $locationService->getLocationModule('campaignchain/location-website', 'campaignchain-website'); $location = new Location(); $location->setLocationModule($locationModule); $location->setName($locationName); $location->setUrl($locationURL); // Get the Website's favicon as Channel image if possible. $favicon = ParserUtil::getFavicon($locationURL); if ($favicon) { $locationImage = $favicon; } else { // $locationImage = $this->container->get('templating.helper.assets') // ->getUrl( // 'bundles/campaignchainlocationwebsite/images/icons/256x256/website.png', // null // ); $locationImage = null; } $location->setImage($locationImage); $wizard = $this->get('campaignchain.core.channel.wizard'); $wizard->setName($location->getName()); $repository = $this->getDoctrine()->getRepository('CampaignChainCoreBundle:Location'); if (!$repository->findBy(array('url' => $location->getUrl()))) { $wizard->addLocation($location->getUrl(), $location); try { $channel = $wizard->persist(); $wizard->end(); $this->get('session')->getFlashBag()->add('success', "The Website '" . $location->getUrl() . "' has been connected."); return $this->redirect($this->generateUrl('campaignchain_core_location')); } catch (\Exception $e) { $this->addFlash('warning', "An error occured during the creation of the website location"); $this->get('logger')->addError($e->getMessage()); } } else { $this->addFlash('warning', "The website '" . $location->getUrl() . "' already exists."); } } //return $this->redirect($this->generateUrl( // 'campaignchain_channel_website_page_new', //array('id' => $channel->getLocations()[0]->getId()))); return $this->render('CampaignChainCoreBundle:Base:new.html.twig', array('page_title' => 'Connect Website', 'form' => $form->createView())); }
public function createLocationAction(Request $request) { $selectedIds = $request->get('google-analytics-profile-id', []); if (empty($selectedIds)) { $this->addFlash('warning', 'Please select at least one Google Analytics property'); return $this->redirectToRoute('campaignchain_channel_google_analytics_list_properties'); } /** @var Token $token */ $token = $request->getSession()->get('token'); $em = $this->getDoctrine()->getManager(); $token = $em->merge($token); $websiteChannelModule = $em->getRepository('CampaignChainCoreBundle:ChannelModule')->findOneBy(['identifier' => 'campaignchain-website']); $googleAnalyticsChannelModule = $em->getRepository('CampaignChainCoreBundle:ChannelModule')->findOneBy(['identifier' => 'campaignchain-google-analytics']); foreach ($selectedIds as $analyticsId) { list($accountId, $propertyId, $profileId) = explode('|', $analyticsId); $analyticsClient = $this->get('campaignchain_report_google_analytics.service_client')->getService($token); /** @var \Google_Service_Analytics_Profile $profile */ $profile = $analyticsClient->management_profiles->get($accountId, $propertyId, $profileId); $wizard = $this->get('campaignchain.core.channel.wizard'); $wizard->start(new Channel(), $googleAnalyticsChannelModule); $wizard->setName($profile->getName()); // Get the location module. $locationService = $this->get('campaignchain.core.location'); $locationModule = $locationService->getLocationModule('campaignchain/location-google-analytics', 'campaignchain-google-analytics'); $location = new Location(); $location->setIdentifier($profile->getId()); $location->setName($profile->getName()); $location->setLocationModule($locationModule); $google_base_url = 'https://www.google.com/analytics/web/#report/visitors-overview/'; $location->setUrl($google_base_url . 'a' . $profile->getAccountId() . 'w' . $profile->getInternalWebPropertyId() . 'p' . $profile->getId()); $em->persist($location); try { $em->flush(); } catch (UniqueConstraintViolationException $e) { //This GA endpoint is already connected $this->addFlash('warning', 'The Google Analytics Property <a href="#">' . $profile->getName() . '</a> is already connected.'); continue; } $wizard->addLocation($location->getIdentifier(), $location); $wizard->persist(); $wizard->end(); //Check if the if the belonging website location exists, if not create a new website location $website = $em->getRepository('CampaignChainCoreBundle:Location')->findOneByUrl($profile->getWebsiteUrl()); //Create website location that belongs to the GA location if (!$website) { $websiteLocationModule = $locationService->getLocationModule('campaignchain/location-website', 'campaignchain-website'); $websiteLocationName = ParserUtil::getHTMLTitle($profile->getWebsiteUrl()); $websiteLocation = new Location(); $websiteLocation->setLocationModule($websiteLocationModule); $websiteLocation->setName($websiteLocationName); $websiteLocation->setUrl($profile->getWebsiteUrl()); $em->persist($websiteLocation); $wizard->start(new Channel(), $websiteChannelModule); $wizard->setName($websiteLocationName); $wizard->addLocation($profile->getWebsiteUrl(), $websiteLocation); $wizard->persist(); $website = $websiteLocation; } $entityToken = clone $token; $entityToken->setLocation($location); $entityToken->setApplication($token->getApplication()); $em->persist($entityToken); $analyticsProfile = new Profile(); $analyticsProfile->setAccountId($profile->getAccountId()); $analyticsProfile->setPropertyId($profile->getWebPropertyId()); $analyticsProfile->setProfileId($profile->getId()); $analyticsProfile->setIdentifier($profile->getId()); $analyticsProfile->setDisplayName($profile->getName()); $analyticsProfile->setLocation($location); $analyticsProfile->setBelongingLocation($website); $em->persist($analyticsProfile); $em->flush(); $this->addFlash('success', 'The Google Analytics Property <a href="#">' . $profile->getName() . '</a> was connected successfully.'); } return $this->redirectToRoute('campaignchain_core_location'); }
public function newApiAction(Request $request, $channel) { $hasError = false; if ($this->has('monolog.logger.tracking')) { $logger = $this->get('monolog.logger.tracking'); } else { $logger = $this->get('logger'); } $logger->info('-------'); $logger->info('Start tracking'); // Check whether the channel has access to tracking. // 1. Has the channel ID been provided if (!$channel) { $msg = 'No Channel Tracking ID provided.'; $logger->error($msg); return $this->errorResponse($msg, $request); } $logger->info('Channel Tracking ID: ' . $channel); // 2. Is it a valid Channel Tracking ID? $channel = $this->getDoctrine()->getRepository('CampaignChainCoreBundle:Channel')->findOneByTrackingId($channel); if (!$channel) { $msg = 'Unknown Channel Tracking ID'; $logger->error($msg); return $this->errorResponse($msg, $request); } // Check whether required parameters have been provided. if (!$request->get('source')) { $hasError = true; $msg = 'URL of source Location missing.'; } elseif (!$request->get('target')) { $hasError = true; $msg = 'URL of target Location missing.'; } if ($hasError) { $logger->error($msg); return $this->errorResponse($msg, $request); } $source = $request->get('source'); $target = $request->get('target'); $trackingIdName = $request->get('id_name'); $logger->info('Tracking ID name: ' . $trackingIdName); $trackingIdValue = $request->get('id_value'); $logger->info('Tracking ID value: ' . $trackingIdValue); $trackingAlias = $request->get('alias'); $logger->info('Tracking Alias: ' . $trackingAlias); if ($this->getParameter('campaignchain_core.tracking.js_mode') == 'dev' || $this->getParameter('campaignchain_core.tracking.js_mode') == 'dev-stay') { $source = ParserUtil::removeUrlParam($source, self::TRACKING_REPORT_BASE_URL_NAME); $target = ParserUtil::removeUrlParam($target, self::TRACKING_REPORT_BASE_URL_NAME); } $sourceUrl = ParserUtil::removeUrlParam($source, $trackingIdName); $targetUrl = ParserUtil::removeUrlParam($target, $trackingIdName); $logger->info('Source: ' . $sourceUrl); $logger->info('Target: ' . $targetUrl); // Check if URLs are valid. $constraint = new Url(); $constraint->message = "Source Location '" . $source . "' is not a valid URL."; $errors = $this->get('validator')->validateValue($source, $constraint); if (count($errors)) { $hasError = true; $msg = $errors[0]->getMessage(); } if (strpos($target, 'mailto') === false) { // Check if we get an absolute or a relative path, if relative, then we can assume it goes to the source host if (!parse_url($target, PHP_URL_HOST) && parse_url($source, PHP_URL_HOST)) { $parsedSource = parse_url($source); $target = (array_key_exists('scheme', $parsedSource) ? $parsedSource['scheme'] : 'http') . '://' . rtrim($parsedSource['host'], '/') . '/' . $target; } $constraint->message = "Target Location '" . $target . "' is not a valid URL."; $errors = $this->get('validator')->validateValue($target, $constraint); if (count($errors)) { $hasError = true; $msg = $errors[0]->getMessage(); } } else { // mailto links are not tracked $hasError = true; $msg = 'Mailto links are not tracked'; } if ($hasError) { $logger->error($msg); return $this->errorResponse($msg, $request); } // Check whether the Tracking ID name has been provided. if ($trackingIdName == null) { $msg = 'No Tracking ID name provided.'; $logger->error($msg); return $this->errorResponse($msg, $request); } // Check whether the Tracking ID name is correct. if ($trackingIdName != $this->getParameter('campaignchain_core.tracking.id_name') && $trackingIdName != 'campaignchain-id') { $msg = 'Provided Tracking ID name ("' . $trackingIdName . '") does not match, should be "' . $this->getParameter('campaignchain_core.tracking.id_name') . '".'; $logger->error($msg); return $this->errorResponse($msg, $request); } if ($trackingIdValue != null) { // Does the CTA for the provided Tracking ID exist? /** @var CTA $cta */ $cta = $this->getDoctrine()->getRepository('CampaignChainCoreBundle:CTA')->findOneByTrackingId($trackingIdValue); if (!$cta) { $msg = 'Unknown CTA Tracking ID "' . $trackingIdValue . '".'; $logger->error($msg); return $this->errorResponse($msg, $request); } // Get the referrer Location. $em = $this->getDoctrine()->getManager(); /** @var QueryBuilder $qb */ $qb = $em->createQueryBuilder(); $qb->select('l')->from('CampaignChain\\CoreBundle\\Entity\\Location', 'l')->from('CampaignChain\\CoreBundle\\Entity\\CTA', 'cta')->where('l.operation = :operation')->andWhere('l.id != cta.location')->andWhere('cta.operation = l.operation')->andWhere('(l.id = :activityLocation OR l.parent = :activityLocation)')->andWhere('l.status = :status')->setParameter('operation', $cta->getOperation())->setParameter('activityLocation', $cta->getOperation()->getActivity()->getLocation())->setParameter('status', Medium::STATUS_ACTIVE); $query = $qb->getQuery(); try { $referrerLocation = $query->getSingleResult(); } catch (\Exception $e) { $msg = Response::HTTP_INTERNAL_SERVER_ERROR . ': Multiple referrers are not possible.'; $logger->error($msg); return $this->errorResponse($msg, $request); } if (!$referrerLocation) { $msg = Response::HTTP_INTERNAL_SERVER_ERROR . ': No referrer Location.'; $logger->error($msg); return $this->errorResponse($msg, $request); } $sourceLocation = null; if ($sourceUrl == $targetUrl) { $logger->info('Source URL == target URL.'); /* * If the source equals the target, then the source is actually * an Activity's CTA. */ $sourceUrl = $cta->getLocation()->getUrl(); $sourceLocation = $cta->getLocation(); $targetLocation = $cta->getLocation(); } else { $logger->info('Source URL != target URL.'); $sourceLocation = $cta->getLocation(); /* * Check if the target URL is in a connected Channel. If yes, add * as new Location if supported by module. */ /** @var LocationService $locationService */ $locationService = $this->container->get('campaignchain.core.location'); try { $logger->info('Searching for matching Location or creating new one.'); $targetLocation = $locationService->findLocationByUrl($targetUrl, $cta->getOperation(), $trackingAlias); if ($targetLocation) { $logger->info('Found target Location with bundle ' . $targetLocation->getLocationModule()->getBundle()->getName() . ' and module ' . $targetLocation->getLocationModule()->getIdentifier() . '.'); } else { $logger->info('No matching Location found, nor a new one created.'); } } catch (\Exception $e) { $msg = Response::HTTP_INTERNAL_SERVER_ERROR . ': ' . $e->getMessage(); $logger->error($msg); return $this->errorResponse($msg, $request); } } // /* // * Check if the source URL provided in CTA record is the same as // * the one passed to this API. // */ // if($cta->getUrl() != $sourceUrl){ // $msg = Response::HTTP_BAD_REQUEST.': Provided source URL "'.$sourceUrl.'" does not match URL for Tracking ID "'.$trackingIdName.'".'; // $logger->error($msg); // $response = new Response($msg); // return $response->setStatusCode(Response::HTTP_BAD_REQUEST); // } // // Verify that the source exists as a Location within CampaignChain. // $location = $this->getDoctrine() // ->getRepository('CampaignChainCoreBundle:Location') // ->findOneBy(array('URL' => $sourceUrl)); // // if (!$location) { // $response = new Response('A Location does not exist for URL "'.$sourceUrl.'".'); // return $response->setStatusCode(Response::HTTP_BAD_REQUEST); // } // Add new CTA to report. $reportCTA = new ReportCTA(); $reportCTA->setCTA($cta); $reportCTA->setOperation($cta->getOperation()); $reportCTA->setActivity($cta->getOperation()->getActivity()); $reportCTA->setCampaign($cta->getOperation()->getActivity()->getCampaign()); $reportCTA->setChannel($cta->getOperation()->getActivity()->getChannel()); $reportCTA->setReferrerLocation($referrerLocation); $reportCTA->setReferrerName($referrerLocation->getName()); $reportCTA->setReferrerUrl($referrerLocation->getUrl()); $reportCTA->setSourceLocation($sourceLocation); $reportCTA->setSourceName($sourceLocation->getName()); $reportCTA->setSourceUrl($sourceUrl); $reportCTA->setTargetUrl($targetUrl); if ($targetLocation) { $reportCTA->setTargetName($targetLocation->getName()); $reportCTA->setTargetLocation($targetLocation); } else { $reportCTA->setTargetName(ParserUtil::getHTMLTitle($targetUrl)); } $reportCTA->setTime(); $em = $this->getDoctrine()->getManager(); $em->persist($reportCTA); $em->flush(); $logger->info('Done tracking'); $logger->info('-------'); /* * Set the target's affiliation with CampaignChain in the * response. Options are: * * - current: The target URL resides within the current * Location. * - connected: The target URL resides within another * Location which is connected with * CampaignChain. * - unknown: The target URL resides within another * Location which is _not_ connected with * CampaignChain. */ if ($source == $target) { $targetAffiliation = 'connected'; } elseif ($reportCTA->getTargetLocation()) { if ($reportCTA->getTargetLocation()->getChannel()->getTrackingId() == $reportCTA->getSourceLocation()->getChannel()->getTrackingId()) { $targetAffiliation = 'current'; } else { $targetAffiliation = 'connected'; } } else { $targetAffiliation = 'unknown'; } $response = new JsonResponse(['target_affiliation' => $targetAffiliation, 'success' => true]); $response->setCallback($request->get('callback')); return $response; } else { $msg = 'Tracking ID missing as part of source Location.'; $logger->error($msg); return $this->errorResponse($msg, $request); } }