<?php
namespace App\Controller;
use App\Config;
use App\Entity\AffiliateInfo;
use App\Entity\Employees;
use App\Entity\AgentControl;
use App\Entity\MmpMobileApps;
use App\Entity\MmpOffers;
use App\Entity\MmpReports;
use App\Entity\OfferInfo;
use App\Entity\NewsletterBuilder;
use App\Entity\OfferGeoRelationship;
use App\Services\AffiliateHasofferAPI;
use App\Services\Alerts;
use App\Services\Aws\ElasticCache;
use App\Services\Aws\S3;
use App\Services\BrandHasofferAPI;
use App\Services\Common;
use App\Services\FinancialToolsComponents;
use App\Services\ImpressionsApis;
use App\Services\Metrics24APICalls;
use App\Services\MmpComponents;
use App\Services\MysqlQueries;
use App\Services\UsersComponents;
use Doctrine\Persistence\ManagerRegistry;
use Mmoreram\GearmanBundle\Service\GearmanClientInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use App\Repository\MafoAdvertiserCabinetManagerMappingWithTuneAdvertiserRepository;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use function GuzzleHttp\json_encode;
/**
*
* @Route("/api/client/advertiser", name="client_advertiser_", host="%advertisers_subdomain%")
*/
class ClientSideAdvertiserController extends AbstractController
{
private $commonCalls;
private $doctrine;
private $mysqlQueries;
private $financialToolsComponents;
private $alerts;
private $brandHasofferApi;
private $mmpComponents;
private $affiliateHasofferAPI;
private $usersComponents;
private $elasticCache;
private $projectDir;
private $s3;
private $impressionsApis;
private $metrics24APICalls;
private $gearmanClientInterface;
private $mappingRepository;
public function __construct(Common $commonCalls, ManagerRegistry $doctrine, MysqlQueries $mysqlQueries, MafoAdvertiserCabinetManagerMappingWithTuneAdvertiserRepository $mappingRepository,
FinancialToolsComponents $financialToolsComponents, Alerts $alerts, BrandHasofferApi $brandHasofferApi, MmpComponents $mmpComponents, AffiliateHasofferAPI $affiliateHasofferAPI, UsersComponents $usersComponents, ElasticCache $elasticCache, S3 $s3, ImpressionsApis $impressionsApis, Metrics24APICalls $metrics24APICalls, GearmanClientInterface $gearmanClientInterface, string $projectDir)
{
$this->commonCalls = $commonCalls;
$this->doctrine = $doctrine;
$this->mysqlQueries = $mysqlQueries;
$this->financialToolsComponents = $financialToolsComponents;
$this->alerts = $alerts;
$this->brandHasofferApi = $brandHasofferApi;
$this->mmpComponents = $mmpComponents;
$this->affiliateHasofferAPI = $affiliateHasofferAPI;
$this->usersComponents = $usersComponents;
$this->elasticCache = $elasticCache;
$this->s3 = $s3;
$this->impressionsApis = $impressionsApis;
$this->metrics24APICalls = $metrics24APICalls;
$this->gearmanClientInterface = $gearmanClientInterface;
$this->projectDir = $projectDir;
$this->mappingRepository = $mappingRepository;
}
/**
* @Route("/validate", name="validate", methods={"GET"})
*/
public function getValidateAction(Request $request)
{
return new JsonResponse(true);
}
/**
* @Route("/login", name="login")
*/
public function indexAction(AuthenticationUtils $authenticationUtils)
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('/advertiser/login/index.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
]);
}
/**
* @Route("/details", name="get_advertiser_details", methods={"GET"})
*/
public function getAdvertiserDetails(Request $request): Response
{
$advertiserInfo = $this->getUser();
$advertiserData = [
'id' => $advertiserInfo->getId(),
'email' => $advertiserInfo->getEmail(),
'firstName' => $advertiserInfo->getFirstName(),
'lastName' => $advertiserInfo->getLastName(),
'status' => $advertiserInfo->getStatus(),
'lastLoginAt' => $advertiserInfo->getLastLoginAt(),
'dateUpdated' => $advertiserInfo->getDateUpdated(),
];
return $this->json($advertiserData);
}
private function getMappedAdvertiserManagersId(int $advertiserId): array
{
$mappedTuneAdvertiserIds = $this->mappingRepository->findMappedTuneAdvertiserIdsByAdvertiserId($advertiserId);
return array_map(fn($item) => $item->getMappedAdvertiserId(), $mappedTuneAdvertiserIds);
}
function removeEmailsFromLabels(array $data): array
{
return array_map(function ($item) {
$item['label'] = preg_replace('/\s*\[.*?\]/', '', $item['label']);
return $item;
}, $data);
}
/**
* @Route("/report-columns/{report}", name="get_report_columns", methods={"GET"})
*/
public function getReportColumnsAction(Request $request, $report)
{
if (in_array($report, array_keys(Config::TABLE_COLUMNS_WITH_JSON_FILE))) {
return new JsonResponse(array_values($this->commonCalls->getDataFromJsonFile(Config::TABLE_COLUMNS_WITH_JSON_FILE[$report])));
} else {
return new JsonResponse(array_values(Config::REPORT_COLUMN_MAPPING[$report]));
}
}
/**
* @Route("/countries", name="get_countries", methods={"GET"})
*/
public function getCountriesAction()
{
$countryList = [];
foreach (Config::COUNTRIES as $key => $value) {
$countryList[$key] = [
'value' => $key,
'label' => $key . ' - ' . $value['name']
];
}
ksort($countryList);
return new JsonResponse(array_values($countryList));
}
/**
* @Route("/boolean-select", name="get_boolean_select", methods={"GET"})
*/
public function getBooleanSelectAction(Request $request)
{
return new JsonResponse([
[
'value' => 1,
'label' => 'YES',
],
[
'value' => 0,
'label' => 'NO',
],
]);
}
/**
* @Route("/mmp-offer-events-by-advertiser", name="get_mmp_offer_events", methods={"GET"})
*/
public function getMmpOfferEventsAction(Request $request)
{
$advertiserInfo = $this->getUser();
$advertiserId = $advertiserInfo->getId();
$mappedAdvertiserIds = $this->getMappedAdvertiserManagersId($advertiserId);
$mmpOffersEvents = $this->doctrine->getRepository(MmpOffers::class)->getEventsByAdvertiserIds($mappedAdvertiserIds);
$arr = [];
foreach ($mmpOffersEvents as $value) {
$eventName = $value['defaultRevenueEvent'];
$arr[] = [
'value' => $eventName,
'label' => $eventName . " [ID: {$eventName}]"
];
}
return new JsonResponse(array_values($arr));
}
/**
* @Route("/offers-by-advertiser", name="get_offers_by_advertiser_id", methods={"GET"})
*/
public function getOffersByAdvertiserAction(Request $request)
{
$advertiserInfo = $this->getUser();
$advertiserId = $advertiserInfo->getId();
$mappedAdvertiserIds = $this->getMappedAdvertiserManagersId($advertiserId);
$offers = [];
$offersByAdvertiser = $this->doctrine->getRepository(MmpOffers::class)->getMmpOfferDataByAdvertiserIds($mappedAdvertiserIds);
foreach ($offersByAdvertiser as $key => $value) {
$offers[] = [
'value' => $value['id'],
'label' => $value['offerName']
];
}
return new JsonResponse($offers);
}
/**
* @Route("/mmp-tracking-system-global-network-report", name="get_mmp-tracking-system-global-network-report", methods={"GET"})
*/
public function getMmpTrackingSystemForGlobalNetworkReportAction(Request $request)
{
$mmpTrackingSystem = [];
foreach (Config::MMP_TRACKING_SYSTEM_GLOBAL_NETWORK_REPORT_PRETTY as $key => $value) {
$mmpTrackingSystem[] = [
'value' => $key,
'label' => $value
];
}
$mmpTrackingSystem = $this->removeEmailsFromLabels($mmpTrackingSystem);
return new JsonResponse($mmpTrackingSystem);
}
/**
* @Route("/mmp-mobile-app-info-by-advertiser", name="get_mmp-mobile-app-info-by-advertiser", methods={"GET"})
*/
public function getMmpMobileAppByAdvertiser(Request $request): JsonResponse
{
try {
$advertiserInfo = $this->getUser();
$advertiserId = $advertiserInfo->getId();
$mappedAdvertiserIds = $this->getMappedAdvertiserManagersId($advertiserId);
// Get status from request, default to active status if not provided
$status = $request->query->get('status', Config::ACTIVE_STATUS);
// Convert status to an array if it's a string (e.g., comma-separated or single value)
if (!is_array($status)) {
$status = explode(',', $status);
}
// Get search keyword from request (default to null if not provided)
$search = $request->query->get('search', null);
// Fetch MMP mobile apps based on advertiserId and status and search keyword
$mmpMobileApps = $this->doctrine
->getRepository(MmpMobileApps::class)
->getMmpMobileAppForAdvertiser($mappedAdvertiserIds, $status, $search);
// Format the response
$formattedMmpMobileApp = array_map(function ($app) {
return [
'value' => $app['bundleId'],
'label' => $app['bundleId'] . " - " . $app['appName'],
];
}, $mmpMobileApps);
return new JsonResponse($formattedMmpMobileApp);
} catch (\Exception $e) {
return new JsonResponse(
[
'success' => false,
'message' => 'Failed to fetch MMP mobile apps.',
'error' => $e->getMessage(),
],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
/**
* @Route("/mapped-ho-offers-with-mmp-offers", name="_mapped_ho_offers_with_mmp_offers")
*/
public function getMappedHoOffersWithMmpOffers(Request $request)
{
$advertiserInfo = $this->getUser();
$advertiserId = $advertiserInfo->getId();
$mappedAdvertiserIds = $this->getMappedAdvertiserManagersId($advertiserId);
$hoOfferByAdvertiser = $this->doctrine->getRepository(OfferInfo::class)->getOfferDataByAdvertiserIds($mappedAdvertiserIds);
$offerData = [];
foreach ($hoOfferByAdvertiser as $key => $value) {
$offerData[] = [
'value' => $value['offerId'],
'label' => $value['name']
];
}
return new JsonResponse(array_values($offerData));
}
private function getAdvertiserManagerData()
{
$advertiserInfo = $this->getUser();
$advertiserId = $advertiserInfo->getId();
$mappedAdvertiserIds = $this->getMappedAdvertiserManagersId($advertiserId);
return [
'formattedArray' => [
'MULTISELECT_MMP_TUNE_ADVERTISERS' => $mappedAdvertiserIds,
],
'$mappedAdvertiserIds' => $mappedAdvertiserIds,
];
}
public function modifyTableColumnHeaders(array $columns): array
{
$headerMapping = [
'Advertiser Id' => 'Advertiser Tune Id',
'Advertiser Name' => 'Advertiser Tune Name',
'Affiliate Id' => 'Partner Id'
];
return array_map(function ($column) use ($headerMapping) {
if (isset($headerMapping[$column['header']])) {
$column['header'] = $headerMapping[$column['header']];
}
return $column;
}, $columns);
}
/**
* @Route("/traffic-report", methods={"GET"})
*/
public function getTrafficReport(Request $request)
{
ini_set('memory_limit', '512M');
$advertiserData = $this->getAdvertiserManagerData();
$formattedTrafficReportArray = $advertiserData['formattedArray'];
$mappedAdvertiserIds = $advertiserData['$mappedAdvertiserIds'];
$filtersSelected = $request->query->get('filters');
$excludedFlagForFilters = $request->query->get('excludedFlagForFilters') ?? [];
$filters = [];
$excludedFiltersFlags = [];
$filtersSelected['MULTISELECT_MMP_TUNE_ADVERTISERS'] = $formattedTrafficReportArray['MULTISELECT_MMP_TUNE_ADVERTISERS'];
if (isset($filtersSelected)) {
foreach ($filtersSelected as $key => $value) {
$key === Config::MULTISELECT_MMP_STATISTICS_APP ? $filters['appIds'] = $value : false;
$key === Config::MULTISELECT_MMP_OFFERS ? $filters['offers'] = $value : false;
$key === Config::MULTISELECT_MMP_SOURCE_GLOBAL_NETWORK_REPORT ? $filters['mmpSource'] = $value : false;
$key === Config::MULTISELECT_GEO ? $filters['geos'] = $value : false;
$key === Config::MULTISELECT_MMP_EVENTS ? $filters['events'] = $value : false;
$key === Config::MULTISELECT_MMP_TUNE_OFFERS ? $filters['hoOfferIds'] = $value : false;
$key === Config::MULTISELECT_MMP_IS_RETARGETED ? $filters['isRetargeted'] = $value : false;
$key === Config::MULTISELECT_MMP_TUNE_ADVERTISERS ? $filters['advertiserIds'] = $value : false;
}
}
if (isset($excludedFlagForFilters)) {
foreach ($excludedFlagForFilters as $key => $value) {
$value = (int)$value;
$key === Config::MULTISELECT_MMP_STATISTICS_APP ? $excludedFiltersFlags['appIds'] = $value : false;
$key === Config::MULTISELECT_MMP_OFFERS ? $excludedFiltersFlags['offers'] = $value : false;
$key === Config::MULTISELECT_MMP_SOURCE_GLOBAL_NETWORK_REPORT ? $excludedFiltersFlags['mmpSource'] = $value : false;
$key === Config::MULTISELECT_GEO ? $excludedFiltersFlags['geos'] = $value : false;
$key === Config::MULTISELECT_MMP_EVENTS ? $excludedFiltersFlags['events'] = $value : false;
$key === Config::MULTISELECT_MMP_TUNE_OFFERS ? $excludedFiltersFlags['hoOfferIds'] = $value : false;
}
}
$selectedColumns = $request->query->get('data') != '' ? $request->query->get('data') : [];
$groupedColumns = $request->query->get('groups') != '' ? $request->query->get('groups') : [];
$dateStart = date('Y-m-d', strtotime($request->query->get('startDate')));
$dateEnd = date('Y-m-d', strtotime($request->query->get('endDate')));
$eventTimestampFrom = strtotime($dateStart);
$eventTimeStampTo = strtotime($dateEnd);
$sortBy = $request->query->get('sortBy') ?? Config::REPORTS_PAGINATION_MMP_REPORT_DEFAULT_SORT_BY;
$sortType = $request->query->get('sortType') ?? Config::REPORTS_PAGINATION_DEFAULT_SORT_TYPE;
$page = $request->query->get('page') ?? Config::REPORTS_PAGINATION_DEFAULT_PAGE_NUMBER;
$limit = $request->query->get('limit') ?? Config::REPORTS_PAGINATION_DEFAULT_PAGE_SIZE;
$downloadDataAsCSV = $request->query->get('downloadCSV') == 'true';
$tableColumns = $this->commonCalls->changeColumnVisibilityForTable(
array_values($this->commonCalls->getDataFromJsonFile(Config::JSON_FILE_GLOBAL_NETWORK_REPORT)),
$selectedColumns, []
);
$tableColumns = $this->modifyTableColumnHeaders($tableColumns);
$finalReportData = $this->mmpComponents->getMmpCumulativeData(
$filters,
$excludedFiltersFlags,
$eventTimestampFrom,
$eventTimeStampTo,
$selectedColumns,
$groupedColumns
);
$finalReportData = $this->mmpComponents->normalizeMmpSource($finalReportData);
foreach ($tableColumns as $key => $value) {
if (isset($value['aggregate']) && $value['aggregate'] == 'sum') {
$num = round(array_sum(array_column($finalReportData, $value['accessor'])), 2);
if ($value['category'] == 'statistics') {
$tableColumns[$key]['Footer'] = number_format($num);
} else {
$tableColumns[$key]['Footer'] = number_format($num, 2);
}
}
}
if ($downloadDataAsCSV) {
$this->commonCalls->downloadCSV($tableColumns, $finalReportData, 'Traffic Report ' . $dateStart . '_' . $dateEnd);
} else {
$finalReportData = array_values($finalReportData);
if (sizeof($finalReportData)) {
$entity = $finalReportData[0];
if (array_key_exists($sortBy, $entity)) {
$sortFlag = 3;
if ($sortType == Config::SORT_TYPE_ASC) {
$sortFlag = 4;
}
array_multisort(array_column($finalReportData, $sortBy), $sortFlag, $finalReportData);
}
}
$offset = $limit * ($page - 1);
$totalRecordCount = sizeof($finalReportData);
$noOfPages = ceil($totalRecordCount / $limit);
return new JsonResponse([
'response' => [
'success' => true,
'httpStatus' => Config::HTTP_STATUS_CODE_OK,
'data' => [
'tableColumns' => $tableColumns,
'data' => array_slice($finalReportData, $offset, $limit),
'metaData' => [
'total' => $totalRecordCount,
'limit' => (int)$limit,
'page' => (int)$page,
'pages' => (int)$noOfPages,
]
],
'error' => null
]
], Config::HTTP_STATUS_CODE_OK);
}
}
}