<?php
namespace App\Controller;
use App\Service\Api;
use App\Twig\AppExtension;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class OrderController extends AbstractController
{
private $appExtension;
private $apiService;
private $logger;
public function __construct(AppExtension $appExtension, Api $apiService, LoggerInterface $logger)
{
$this->appExtension = $appExtension;
$this->apiService = $apiService;
$this->logger = $logger;
}
/*******************************************************************************************
* ORDER ROUTES
*******************************************************************************************/
/**
* @Route("/services/{Service}/{SubService}/{IDSN}/{IDGService}/order/{IDService}", name="order_sub_service")
*/
public function index(Api $apiService, $IDSN, $IDGService, $IDService)
{
$data['services'] = $apiService->getAllServices();
$data['current_service'] = null;
$data['current_sub_service'] = null;
$data['current_offer'] = null;
$data["icons"] = $apiService->getServicesIcons();
// Get the current service
foreach ($data['services'] as $key => $service) {
if ($service['IDSN'] == $IDSN) {
$data['current_service'] = $service;
}
}
// Check if the current service does not exists
if (!$data['current_service']) {
return $this->render('errors/notFoundService.html.twig', $data);
}
// Get the current sub service
foreach ($data['current_service']['subs'] as $key => $subservice) {
if ($subservice['IDGService'] == $IDGService) {
/* ************************************************************************************
TODO:: Demander a Adil de modifier le Process type pour les subservices instagram reels
Une fois c'est fait supprimer cette condition
***************************************************************************************/
if ($subservice["IDGService"] == "ig9" || $subservice["IDGService"] == "ig10") {
$subservice['ProcessType'] = 'ig_reels';
}
$data['current_sub_service'] = $subservice;
}
}
// Get the current offer
foreach ($data['current_sub_service']["offers"] as $key => $offer) {
if ($offer['IDService'] == $IDService) {
$data['current_offer'] = $offer;
}
}
return $this->render('order/order.html.twig', $data);
}
/**
* @Route("/order/add", name="add_order", methods={"POST"})
*/
public function addOrder(Request $request, UrlGeneratorInterface $urlGenerator)
{
// Get the raw JSON data from the request
$jsonData = json_decode($request->getContent(), true);
$this->logger->info("============================== START addOrder ({$request->getContent()}) ==============================");
$orderApiUrl = $this->getParameter('app.orderApiUrl');
$orderApiAddPrefix = $this->getParameter('app.orderApiAddPrefix');
$orderApiCheckoutUrlPrefix = $this->getParameter('app.orderApiCheckoutUrlPrefix');
$params[] = 'token=' . $this->getParameter('app.orderApiToken');
$params[] = 'email=' . $jsonData['email'];
$params[] = 'idservice=' . $jsonData['IDService'];
$params[] = 'lang=' . $jsonData['lang'];
$params[] = 'idcountry=' . $this->appExtension->getCountry();
$params[] = 'currency=' . $this->appExtension->getOrderCurrency();
$params[] = 'ip=' . $this->appExtension->getIp();
// Optionnal params
$params[] = 'username=' . ($jsonData['username'] ?? "");
$params[] = 'url=' . implode("\n", $jsonData['links'] ?? []) ?? "";
$params[] = 'checkoutlink=' . $this->getParameter('app.orderCheckoutUrl');
// Custom comments data
if (isset($jsonData['customComments']) && is_array($jsonData['customComments']) && count($jsonData['customComments']) > 0) {
$arrComments = [];
foreach($jsonData['customComments'] as $key => $comment) {
$arrComments[] = $comment['text'];
}
$params[] = 'customcomments=' . implode("\n", $arrComments ?? []) ?? "";
} else {
$params[] = 'customcomments=';
}
// Create an instance of the HttpClient
$client = HttpClient::create();
// Compose api url to create new order
$apiUrl = $orderApiUrl . '/' . $orderApiAddPrefix . '?' . implode("&", $params);
// Send a GET request to the API URL
$response = $client->request('GET', $apiUrl);
$this->logger->info('Api order PARAMS : ', [$params]);
$this->logger->info('Api order URL : ', [$apiUrl]);
$this->logger->info('Api order Response : ', [$response->getContent()]);
// Get the content of the response
$orderId = substr($response->getContent(), 1, -1) ;
$this->logger->info('Generated order id : ', [$orderId]);
$params = [];
$params[] = 'token=' . $this->getParameter('app.orderApiToken');
$params[] = 'orderid=' . $orderId;
// Compose api payment url
$apiPaymentUrl = $orderApiUrl . '/' . $orderApiCheckoutUrlPrefix . '?' . implode("&", $params);
// Send a GET request to the API URL
$response = $client->request('GET', $apiPaymentUrl);
// Get the content of the response
$orderUrl = substr($response->getContent(), 1, -1);
$this->logger->info('Api payment PARAMS : ', [$params]);
$this->logger->info('Api payment URL : ', [$apiPaymentUrl]);
$this->logger->info('Api payment Response : ', [$response->getContent()]);
// Compose result
$result = ["redirect_url" => $orderUrl];
return new JsonResponse($result);
}
/**
* @Route("/order/relaunch/{order}", name="order_relaunch")
*/
public function relaunch(Api $apiService, $order)
{
$content = $apiService->relaunchOrder($order);
if(strtolower(str_replace("\"",'',strtolower($content)))=='error'){
return $this->render('errors/errorRelaunch.html.twig');
}
else{
return $this->render('order/reluanch.html.twig');
}
}
function printr($data) {
echo "<pre>" . print_r($data,true) . "</pre>";
}
/**
* @Route("/order/success/{order}", name="order_succeeded")
*/
public function success(Api $apiService, $order)
{
$data['services'] = $apiService->getAllServices();
$data["icons"] = $apiService->getServicesIcons();
$data["order"] = $apiService->getOrderDetails($order);
$offers = [];
$services = [];
foreach ($data['services'] as $i => $service) {
foreach ($service['subs'] as $j => $sub) {
$services[$sub['IDGService']] = $sub;
$services[$sub['IDGService']]['service'] = $service;
foreach ($sub['offers'] as $k => $offer) {
$offers[$offer['IDService']] = $offer;
$offers[$offer['IDService']]['sub'] = $sub;
$offers[$offer['IDService']]['sub']['service'] = $service;
if ($offer['IDService'] == $data["order"]['idservice']) {
$data["order"]['offer'] = $offers[$offer['IDService']];
}
}
}
}
$data['related_services'] = [];
if ($data['order']['offer']['sub']['RelatedServiceID1'] != "" && isset($services[$data['order']['offer']['sub']['RelatedServiceID1']])) {
$data['related_services'][] = $services[$data['order']['offer']['sub']['RelatedServiceID1']];
}
if ($data['order']['offer']['sub']['RelatedServiceID2'] != "" && isset($services[$data['order']['offer']['sub']['RelatedServiceID2']])) {
$data['related_services'][] = $services[$data['order']['offer']['sub']['RelatedServiceID2']];
}
if ($data['order']['offer']['sub']['RelatedServiceID3'] != "" && isset($services[$data['order']['offer']['sub']['RelatedServiceID3']])) {
$data['related_services'][] = $services[$data['order']['offer']['sub']['RelatedServiceID3']];
}
$data['order']['id'] = $order;
$data['order']['arrUrls'] = explode('_', $data["order"]['url']);
$this->setFacebookPixel($data['order']['offer']['Price'],$data['order']['email']);
return $this->render('order/success.html.twig', $data);
}
public function getCountry(){
return $_SERVER["HTTP_CF_IPCOUNTRY"];
}
function setFacebookPixel($value,$email){
$accessToken = 'EAAIZAHDJ6RdsBO0cS27GKb6sMtmMJqgSZA80KIdBHTcfkYO2irpco10MP7jvNE9QZBbVwSZCUQluJJiq3ZAS28el7f689NdcPQiZBY2Y8c5PRSo01r96DzOowyjnavTBepIRgdZAZB0s6GRImgY7X7TGNFGytoZAbhdVKMB3ODyA6BServwZC9FJHZCJT8VAgZAlOQfZCPAZDZD';
$pixelId = '741206834880599';
// User data
$userData = [
'em' => hash('sha256', $email),
'country' => hash('sha256', $this->getCountry()),
'client_user_agent' => hash('sha256',$_SERVER['HTTP_USER_AGENT']),
'client_ip_address' =>$_SERVER['HTTP_CF_CONNECTING_IP']
];
// Event data
$eventData = [
'event_name' => 'Purchase',
'event_time' => time(),
'action_source' => 'website',
'event_source_url' => 'https://wizzsocial.com/order/success',
'user_data' => $userData,
'custom_data' => [
'currency' => 'USD',
'value' => $value // Set the value here directly
]
];
// Conversions API endpoint
$url = "https://graph.facebook.com/v13.0/{$pixelId}/events?access_token={$accessToken}";
// Prepare data for JSON
$data = [
'data' => [$eventData]//,
//'test_event_code' => 'TEST62299' // Optional, for testing events
];
// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Execute and fetch the response
$response = curl_exec($ch);
// Check for errors
if (curl_errno($ch)) {
//echo 'Error: ' . curl_error($ch);
} else {
//echo 'Event sent successfully: ' . $response;
}
// Close cURL
curl_close($ch);
}
/**
* @Route("/order/failed/{order}", name="order_failed")
*/
public function failure(Api $apiService, $order)
{
$data['services'] = $apiService->getAllServices();
$data["icons"] = $apiService->getServicesIcons();
return $this->render('order/failed.html.twig', $data);
}
/**
* @Route("/order/checkout/{order}", name="order_checkout")
*/
public function checkout(Api $apiService, $order)
{
$data['services'] = $apiService->getAllServices();
$data["icons"] = $apiService->getServicesIcons();
$data["order"] = $apiService->getOrderDetails($order);
$offers = [];
$services = [];
foreach ($data['services'] as $i => $service) {
foreach ($service['subs'] as $j => $sub) {
$services[$sub['IDGService']] = $sub;
$services[$sub['IDGService']]['service'] = $service;
foreach ($sub['offers'] as $k => $offer) {
$offers[$offer['IDService']] = $offer;
$offers[$offer['IDService']]['sub'] = $sub;
$offers[$offer['IDService']]['sub']['service'] = $service;
if ($offer['IDService'] == $data["order"]['idservice']) {
$data["order"]['offer'] = $offers[$offer['IDService']];
}
}
}
}
$data['related_services'] = [];
if ($data['order']['offer']['sub']['RelatedServiceID1'] != "" && isset($services[$data['order']['offer']['sub']['RelatedServiceID1']])) {
$data['related_services'][] = $services[$data['order']['offer']['sub']['RelatedServiceID1']];
}
if ($data['order']['offer']['sub']['RelatedServiceID2'] != "" && isset($services[$data['order']['offer']['sub']['RelatedServiceID2']])) {
$data['related_services'][] = $services[$data['order']['offer']['sub']['RelatedServiceID2']];
}
if ($data['order']['offer']['sub']['RelatedServiceID3'] != "" && isset($services[$data['order']['offer']['sub']['RelatedServiceID3']])) {
$data['related_services'][] = $services[$data['order']['offer']['sub']['RelatedServiceID3']];
}
$data['order']['id'] = $order;
$orderApiUrl = $this->getParameter('app.orderApiUrl');
$orderApiCheckoutUrlPrefix = $this->getParameter('app.orderApiCheckoutUrlPrefix');
$params = [];
$params[] = 'token=' . $this->getParameter('app.orderApiToken');
$params[] = 'orderid=' . $data['order']['id'];
// Compose api payment url
$apiPaymentUrl = $orderApiUrl . '/' . $orderApiCheckoutUrlPrefix . '?' . implode("&", $params);
// Create an instance of the HttpClient
$client = HttpClient::create();
// Send a GET request to the API URL
$response = $client->request('GET', $apiPaymentUrl);
// Get the content of the response
$orderUrl = substr($response->getContent(), 1, -1);
$data['order']['paymentUrl'] = $orderUrl;
$data['order']['arrUrls'] = explode('_', $data["order"]['url']);
return $this->render('order/checkout.html.twig', $data);
}
/*******************************************************************************************
* INSTAGRAM ROUTES
*******************************************************************************************/
/**
* @Route("/instagram/load-posts", name="load_instagram_posts")
*/
public function loadInstagramPosts(Request $request): JsonResponse
{
// Get instagram infos profile
$return['profile'] = $this->apiService->executeApiUrls("instagram", "infosprofil", $request->query->get("username"),null);
// Check if the returned profile has media_count property
if (isset($return['profile']['media_count'])) {
// Get instagram posts
$return['posts'] = $this->apiService->executeApiUrls("instagram", "posts", $request->query->get("username"),$request->query->get("token"));
return new JsonResponse($return);
} else {
// Return invalid instagram username
return new JsonResponse(["message" => "Instagram username not found. Please try an existing one."], JsonResponse::HTTP_BAD_REQUEST);
}
}
// /**
// * @Route("/instagram/load-posts", name="load_instagram_posts")
// */
// public function loadInstagramPosts(Request $request): JsonResponse
// {
// // Get instagram infos profile
// $return['profile'] = $this->apiService->executeApiUrls("instagram", "infosprofil", $request->query->get("username"));
//
// // Check if the returned profile has media_count property
// if (isset($return['profile']['media_count'])) {
//
// // Check if returned profile media_count property is greater that 0 (means there is posts for the specified account)
// if ($return['profile']['media_count'] > 0) {
//
// // Get instagram posts
// $return['posts'] = $this->apiService->executeApiUrls("instagram", "posts", $request->query->get("username"));
//
// if (count($return['posts']) == 0) {
//
// // Return account has no post error
// return new JsonResponse(["message" => "No posts found. Please make sur your instagram account contains posts and is not private"], JsonResponse::HTTP_BAD_REQUEST);
// }
// } else {
//
// // Return account has no post error
// return new JsonResponse(["message" => "No posts found. Please make sur your instagram account contains posts and is not private"], JsonResponse::HTTP_BAD_REQUEST);
// }
// } else {
//
// // Return invalid instagram username
// return new JsonResponse(["message" => "Instagram username not found. Please try an existing one."], JsonResponse::HTTP_BAD_REQUEST);
// }
//
// return new JsonResponse($return);
// }
/**
* @Route("/instagram/load-profile", name="load_instagram_profile")
*/
public function loadInstagramProfile(Request $request): JsonResponse
{
// Get instagram infos profile
$return['profile'] = $this->apiService->executeApiUrls("instagram", "infosprofil", $request->query->get("username"),null);
return new JsonResponse($return);
}
/**
* @Route("/instagram/load-reels", name="load_instagram_reel")
*/
public function loadInstagramReels(Request $request)
{
// Get instagram infos profile
$return['profile'] = $this->apiService->executeApiUrls("instagram", "infosprofil", $request->query->get("username"),$request->query->get("token"));
// Check if the returned profile has media_count property
if (isset($return['profile']['media_count'])) {
// Get instagram posts
$return['posts'] = $this->apiService->executeApiUrls("instagram", "reels", $request->query->get("username"),$request->query->get("token"));
return new JsonResponse($return);
} else {
// Return invalid instagram username
return new JsonResponse(["message" => "Instagram username not found. Please try an existing one."], JsonResponse::HTTP_BAD_REQUEST);
}
}
// /**
// * @Route("/instagram/load-reels", name="load_instagram_reel")
// */
// public function loadInstagramReels(Request $request)
// {
// // Get instagram infos profile
// $return['profile'] = $this->apiService->executeApiUrls("instagram", "infosprofil", $request->query->get("username"));
//
// // Check if the returned profile has media_count property
// if (isset($return['profile']['media_count'])) {
//
// // Check if returned profile media_count property is greater that 0 (means there is posts for the specified account)
// if ($return['profile']['media_count'] > 0) {
//
// // Get instagram posts
// $return['posts'] = $this->apiService->executeApiUrls("instagram", "reels", $request->query->get("username"));
//
// if (count($return['posts']) == 0) {
// // Return account has no post error
// return new JsonResponse(["message" => "No reels found. Please make sur your instagram account contains reels and is not private"], JsonResponse::HTTP_BAD_REQUEST);
// }
// } else {
//
// // Return account has no post error
// return new JsonResponse(["message" => "No posts found. Please make sur your instagram account contains posts and is not private"], JsonResponse::HTTP_BAD_REQUEST);
// }
// } else {
//
// // Return invalid instagram username
// return new JsonResponse(["message" => "Instagram username not found. Please try an existing one."], JsonResponse::HTTP_BAD_REQUEST);
// }
//
// return new JsonResponse($return);
// }
/*******************************************************************************************
* TIKTOK ROUTES
*******************************************************************************************/
/**
* @Route("/tiktok/load-posts", name="load_tiktok_posts")
*/
public function loadTikTokPosts(Request $request)
{
// Get tiktok infos profile
$return['profile'] = $this->apiService->executeApiUrls("tiktok", "infosprofil", $request->query->get("username"));
// Check if the returned profile has videoCount property
if (isset($return['profile']['videoCount'])) {
// Check if returned profile videoCount property is greater that 0 (means there is posts for the specified account)
if ($return['profile']['videoCount'] > 0) {
// Get tiktok posts
$return['posts'] = $this->apiService->executeApiUrls("tiktok", "posts", $request->query->get("username"));
$return['posts'] = $return['posts']['media'];
if (count($return['posts']) == 0) {
// Return account has no post error
return new JsonResponse(["message" => "No posts found. Please make sur your tiktok account contains posts and is not private"], JsonResponse::HTTP_BAD_REQUEST);
}
} else {
// Return account has no post error
return new JsonResponse(["message" => "No posts found. Please make sur your tiktok account contains posts and is not private"], JsonResponse::HTTP_BAD_REQUEST);
}
} else {
// Return invalid tiktok username
return new JsonResponse(["message" => "Tiktok username not found. Please try an existing one."], JsonResponse::HTTP_BAD_REQUEST);
}
return new JsonResponse($return);
}
/**
* @Route("/tiktok/load-profile", name="load_tiktok_profile")
*/
public function loadTikTokProfile(Request $request)
{
// Get instagram infos profile
$return['profile'] = $this->apiService->executeApiUrls("tiktok", "infosprofil", $request->query->get("username"));
// Check if the returned profile doesn't have videoCount property
if (!isset($return['profile']['videoCount'])) {
// Return invalid instagram username
return new JsonResponse(["message" => "TikTok username not found. Please try an existing one."], JsonResponse::HTTP_BAD_REQUEST);
}
return new JsonResponse($return);
}
}