<?php
namespace App\Controller\Uniqskills;
use App\Entity\Gos\Category;
use App\Entity\Gos\Coupon;
use App\Entity\Gos\OrderPart;
use App\Entity\Gos\PortalSettings;
use App\Entity\Gos\ProductVariant;
use App\Entity\Gos\Uniqskills\Course;
use App\Utils\LandingCourse;
use App\Utils\SalesManago\SalesManagoEvent;
use App\Utils\Uniqskills\CourseCatalog;
use App\Utils\Uniqskills\FrontendCategoryTree;
use App\Utils\Uniqskills\MixPanel\MixPanelService;
use App\Utils\Uniqskills\SuggestedCoursesService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Twig\Environment;
/**
* @Route("/{_locale}")
*/
class ZUSCatalogueController extends AbstractController
{
private EntityManagerInterface $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* @Route("/preview/video/{video}/{courseId}", name="fmUniqskillsVideoPreview")
*/
public function showPreviewVideoAction(SalesManagoEvent $salesManagoEvent, $video, $courseId = 0): Response
{
$course = $this->em->getRepository(Course::class)->find($courseId);
$salesManagoEvent->sendDownloadEvent($this->getUser(), $course);
return $this->render('uniqskills/catalogue/landing_new/landing_partials/videoPreview.html.twig', ['video' => $video]);
}
/**
* @Route("/kursy/{page}", name="fmUniqskillsFrontendPlCourseCataloguePage", requirements={"page"="\d+"})
* @Route("/kursy/{category}/{page}", name="fmUniqskillsFrontendPlCourseCatalogue", requirements={"page"="\d+"})
* @Route("/kursy/{category}/{subCategory}/{page}", name="fmUniqskillsFrontendPlCatalogueSubCategory", requirements={"page"="\d+"})
* @Route("/courses/{page}", name="fmUniqskillsFrontendUKCourseCataloguePage", requirements={"page"="\d+"})
* @Route("/courses/{category}/{page}", name="fmUniqskillsFrontendUKCourseCatalogue", requirements={"page"="\d+"})
* @Route("/courses/{category}/{subCategory}/{page}", name="fmUniqskillsFrontendUKCatalogueSubCategory", requirements={"page"="\d+"})
* @Route("/cursos/{page}", name="fmUniqskillsFrontendCourseCataloguePage", requirements={"page"="\d+"})
* @Route("/cursos/{category}/{page}", name="fmUniqskillsFrontendCourseCatalogue", requirements={"page"="\d+"})
* @Route("/cursos/{category}/{subCategory}/{page}", name="fmUniqskillsFrontendCatalogueSubCategory", requirements={"page"="\d+"})
* @Template()
*/
public function courseCatalogueAction(
Request $request,
FrontendCategoryTree $categoryTreeService,
CourseCatalog $courseCatalogService,
MixPanelService $mixPanelService,
$category = null,
$subCategory = null,
$page = 1
) {
if ($request->getSession()->get('send_to_salesmanago')) {
$request->getSession()->remove('send_to_salesmanago');
}
// task GOS-1568
if (in_array($request->getLocale(), ['es', 'pt']) == true) {
return $this->redirectToRoute('fmUniqskillsHomePage');
}
$userCourseIdArray = $courseCatalogService->getUserCourse();
$portalSettings = $this->em->getRepository(PortalSettings::class)
->find($request->getSession()->get('domain'));
$country = $courseCatalogService->getCountry($request);
$categories = $categoryTreeService->getCategoryTree(
$request->getLocale(),
$userCourseIdArray,
$portalSettings->getId()
);
if ($searchQuery = $request->query->get('search'))
{
$mixPanelService->sendSearchQueryEvent($searchQuery, $this->getUser());
}
$pagination = $courseCatalogService->preparePagination(
[
'locale' => $request->getLocale(),
'category' => $category,
'subCategory' => $subCategory,
'page' => $page,
'keyword' => $request->query->get('keyword', 0),
'duration' => $request->query->get('duration', 0),
'priceRange' => $request->query->get('priceRange', 0),
'searchQuery' => $searchQuery
],
$userCourseIdArray,
$country,
$portalSettings
);
$breadcrumbs = $courseCatalogService->prepareBreadcrumbs($category, $subCategory);
$keywords = $courseCatalogService->prepareKeywords(
$category,
$subCategory,
$request->getLocale(),
$userCourseIdArray
);
$categoryEntity = $this->em->getRepository(Category::class)
->findOneBy(
[
'categorySlug' => $subCategory ?? $category,
'portalSettings' => $portalSettings->getId(),
'isActive' => true
]
);
if (is_null($categoryEntity)
&& !in_array($request->get('_route'), ['fmUniqskillsFrontendPlCourseCataloguePage', 'fmUniqskillsFrontendUKCourseCataloguePage'])
)
{
$route = $_ENV['DEFAULT_LOCALE'] === 'pl'
? 'fmUniqskillsFrontendPlCourseCataloguePage'
: 'fmUniqskillsFrontendUKCourseCataloguePage';
return $this->redirectToRoute($route);
}
$parameters = [
'pagination' => $pagination,
'categories' => $categories,
'category' => $categoryEntity,
'country' => $country,
'breadcrumbs' => $breadcrumbs,
'keywords' => $keywords
];
return $request->isXmlHttpRequest()
? $this->render('/uniqskills/catalogue/course_catalogue_ajax.html.twig', $parameters)
: $this->render('/uniqskills/catalogue/course_catalogue.html.twig', $parameters);
}
/**
* @Route("/{categorySlug}/{slug}/{googleAnalSlug}", name="fmUniqskillsCourseLanding")
* @Route("/{categorySlug}/{subCategory}/{keyword}/{slug}/", name="fmUniqskillsCourseLandingExpanded",
* requirements={"categorySlug"="^(?!fm\-admin).*"})
* @Route("/{slug}/", name="fmUniqskillsCourseLandingNoCategory", requirements={"slug"="^(?!.*(login|login_check|logout|register|reset)).*$"}))
*/
public function courseLandingAction(
Request $request,
LandingCourse $landingCourseUtils,
SuggestedCoursesService $suggestedCoursesService,
AuthorizationCheckerInterface $authorizationChecker,
Environment $twig,
ParameterBagInterface $parameterBag,
RouterInterface $router,
$slug,
$googleAnalSlug = null,
$categorySlug = null,
$subCategory = null,
$keyword = null
)
{
/** @var Course $course */
$em = $this->em;
$user = $this->getUser();
$course = $this->em->getRepository(Course::class)->findOneBySlug($slug);
// task GOS-1569
if (empty($course) || in_array($request->getLocale(), ['es', 'pt']) == true)
{
return $this->redirectToRoute('fmUniqskillsHomePage');
}
if (!is_null($course))
{
$request->getSession()->set('courseNameUS', $course->getName());
}
$data = $landingCourseUtils->prepareLandingData($course, $user);
$redirect = $landingCourseUtils->landingRedirect(
[
'slug' => $slug,
'categorySlug' => $categorySlug,
'subCategory' => $subCategory,
'keyword' => $keyword
],
$course,
$request->getLocale()
);
if ($redirect)
{
if ($redirect === '404')
{
throw $this->createNotFoundException('uniqskills');
}
if (is_string($redirect))
{
return $this->redirect($redirect);
}
//add all get parameters to redirect url
foreach ($request->query->all() as $key => $param)
{
$redirect['parameters'][$key] = $param;
}
return $this->redirectToRoute($redirect['route'], $redirect['parameters'], 301);
}
if ($course->getHasMedicalContent() && !$request->cookies->getBoolean('hideMedicalContentWarning'))
{
return $this->render('uniqskills/catalogue/landing_medical_content.html.twig', ['course' => $course]);
}
$landingFile = 'landing/'
. $course->getCategory()->getLanguage()->getCode()
. '/' . $course->getSlug()
. '/index.html.twig';
$landing = $course->getNewLandingPage();
$landingTemplateMenu = false;
$buttonToCountryNotFound = false;
if ($landing && $landing->getIsActive())
{
$landingPath = '/uniqskills/catalogue/landing.html.twig';
if($landing->getTemplate() == 'new') {
$landingPath = '/uniqskills/catalogue/landing_new/landing.html.twig';
$landingTemplateMenu = true;
}
if ($landing->getTemplate() === 'US2024') {
$landingPath = '/uniqskills/catalogue/landing_US2024/landing.html.twig';
}
//if there are no productVariant for country and country is poland show error, else show price in USD and button to show error
if (
empty($data['productVariants'])
&& strtoupper($request->getSession()->get('myCountryCode')) == 'PL'
&& !$authorizationChecker->isGranted('ROLE_ADMIN')
)
{
return $this->redirectToRoute('fmUniqskillsOrderError', [
'request' => $request,
'slugCourse' => $course->getSlug()
]);
}
elseif (empty($data['productVariants']))
{
$buttonToCountryNotFound = [
'route' => 'fmUniqskillsOrderError',
'request' => $request,
'slugCourse' => $course->getSlug()
];
}
}
elseif (file_exists($landingFile))
{
$landingPath = '@landing/' . $landingFile;
// replace old variables price to new
$landingCourseUtils->replaceOldVariablesPriceToNew($course);
$landingCourseUtils->appendScriptToBody($course);
}
else
{
return $this->redirectToRoute('fmUniqskillsFrontendPlCourseCataloguePage');
}
$orderPart = $this->em->getRepository(OrderPart::class)->findOrdersByIdCourse($course->getId());
$realSales = count($orderPart);
$countOrders = $realSales * 3 > 200
? $realSales
: ($realSales * 3 > 9
? $realSales * 3
: 9
);
$showTimer = false;
if((!$course->getIsContinuous()) && $course->getStartDate() && ($course->getStartDate() >= (new \DateTime())))
{
$showTimer = $course->getStartDate();
}
$cooperators = [];
$cooperatorsOption['color'] = null;
$cooperatorsOption['center'] = null;
$cooperatorsOption['title'] = null;
$subscriptions = [];
$landingPack = $landing ? $landingCourseUtils->buildLandingData($landing) : null;
$courseTitleRGBA = null;
$defaultProductVariant = null;
if ($landingPack)
{
foreach ($landingPack['modules'] as $module)
{
if ($module['type'] == 'cooperators')
{
$cooperatorsOption['color'] = $module['headerColor'] ?? null;
$cooperatorsOption['center'] = $module['centeredPosition'] ?? null;
$cooperatorsOption['title'] = $module['cooperationTitle'] ?? null;
foreach ($module['cooperatorList'] as $index => $cooperator)
{
if (
isset($cooperator['show'])
&& $cooperator['show']
&& isset($module['cooperatorsFile_' . $index])
)
{
$cooperators[] = [
'url' => $cooperator['url'] ?? '',
'image' => $module['cooperatorsFile_' . $index]
];
}
}
}
if ($module['type'] == 'payment')
{
$subscriptions = $module['subscriptions'];
if (!empty($subscriptions[0]['subscription']))
{
$defaultProductVariant = $this->em->getRepository(ProductVariant::class)->find($subscriptions[0]['subscription']);
}
foreach ($subscriptions as $subscription)
{
$spv = $this->em->getRepository(ProductVariant::class)->find($subscription['subscription']);
if ($spv->getIsRecurringSubscription() && $spv->getProductVariantNo() == '1')
{
$subscriptionProductVariant = $this->em->getRepository(ProductVariant::class)->findOneBy([
'productVariantNoComplete' => substr_replace($spv->getProductVariantNoComplete(), '2', -1)
]);
}
}
}
if ($module['type'] == 'courseTitle')
{
if (isset($module['overlayColor']) && strlen($module['overlayColor']))
{
$opacity = 1;
if (isset($module['overlayColorAlpha']) && strlen($module['overlayColorAlpha']))
{
$opacity = $module['overlayColorAlpha'];
}
$courseTitleRGBA = $this->hex2rgba($module['overlayColor'], $opacity);
}
}
if ($module['type'] == 'courseProgram')
{
$freeLessonsInCourse = $landingCourseUtils->getFreeLessonsInCourse($module['json']);
}
}
}
// suggested courses
$suggestedCourses = $suggestedCoursesService->findSuggestedCourses($course);
// discount code
$discountCodeExpire = null;
if (isset($data['productVariants']) && count($data['productVariants']))
{
$now = new \DateTime();
if ($course->getIsContinuous() || (!$course->getIsContinuous() && ($landingCourseUtils->calcDateDiff($now, $course->getStartDate()) > 0)))
{
foreach ($subscriptions as $subscription)
{
if (isset($subscription['discountCode']) && $subscription['discountCode'])
{
/** @var Coupon $discountCode */
$discountCode = $this->em->getRepository(Coupon::class)->findOneBy(['id' => $subscription['discountCode']]);
if ($discountCode && $landingCourseUtils->dateInBetween($now, $discountCode->getDateFrom(), $discountCode->getDateTo()))
{
$discountCodeExpire = $discountCode->getDateTo();
}
}
}
}
}
$referer = $request->headers->get('referer');
if (is_null($referer) OR $referer == $request->getUri()
OR (strpos($referer, '/kursy') === false AND $request->getLocale() == 'pl')
OR (strpos($referer, '/cursos') === false AND $request->getLocale() != 'pl'))
{
if ($request->getLocale() == 'pl')
$referer = $this->generateUrl('fmUniqskillsFrontendPlCourseCataloguePage', [], UrlGeneratorInterface::ABSOLUTE_URL);
else
$referer = $this->generateUrl('fmUniqskillsFrontendCourseCataloguePage', [], UrlGeneratorInterface::ABSOLUTE_URL);
}
$user = $this->getUser();
if ($user)
{
$response = new Response();
$response->headers->setCookie(
new Cookie('landingUrl', $request->getUri())
);
$response->sendHeaders();
}
$session = new Session();
$temporaryUserLogin = $session->get('temporaryUserLogin');
$twig->enableAutoReload();
return $this->render($landingPath, [
'course' => $course,
'landing' => $landingPack,
'startDate' => $course->getShareDate() ? $course->getShareDate()->format('m-d-Y') : '',
'countOrders' => $countOrders,
'login' => $router->generate('fos_user_security_login'),
'register' => $router->generate('fos_user_registration_register'),
'preview' => false,
'currency' => '',
'courseOrderLink' => '#subBox',
'productVariants' => $data['productVariants'],
'productPacks' => $data['productPacks'],
'countryEntity' => $data['countryEntity'],
'courseOrderLinkSub' => $data['courseOrderLinkSub'],
'courseGiftLinkSub' => $data['courseGiftLinkSub'],
'codeHead' => $data['config']->getPortalHeadScripts(),
'codeBodyStart' => $data['config']->getPortalStartBodyScripts(),
'codeBodyEnd' => $data['config']->getPortalBodyScripts(),
'subscriptionInfo' => $data['productVariantInfo'],
'showTimer' => $showTimer,
'cooperators' => $cooperators,
'defaultProductVariant' => $defaultProductVariant,
'subscriptionForDefaultPrice' => $subscriptions,
'courseTitleRGBA' => $courseTitleRGBA,
'suggestedCourses' => $suggestedCourses,
'landingTemplateMenu' => $landingTemplateMenu,
'buttonToCountryNotFound' => $buttonToCountryNotFound,
'discountCodeExpire' => $discountCodeExpire,
'referer' => $referer,
'temporaryUserLogin' => $temporaryUserLogin,
'subscriptionProductVariant' => $subscriptionProductVariant ?? '',
'cooperatorsOption' => $cooperatorsOption,
'freeLessonsInCourse' => $freeLessonsInCourse ?? '',
'recaptchaPublicKey' => $parameterBag->get('ewz_recaptcha.public_key')
]);
}
/**
* @Route("/checkLandingPrice/{idCourse}", name="fmUniqskillsCheckLandingPrice")
*/
public function checkLandingPriceAction(LandingCourse $landingCourseUtils, $idCourse): Response
{
/** @var Course $course */
$course = $this->em->getRepository(Course::class)->find($idCourse);
$landing = $course->getNewLandingPage();
$user = $this->getUser();
$data = $landingCourseUtils->prepareLandingData($course, $user);
$subscriptions = [];
$defaultProductVariant = null;
$landingPrice = false;
if ($landing)
{
$landingPack = $landingCourseUtils->buildLandingData($landing);
foreach ($landingPack['modules'] as $module)
{
if ($module['type'] == 'payment')
{
$subscriptions = $module['subscriptions'];
if (!empty($subscriptions[0]['subscription']))
{
$defaultProductVariant = $this->em->getRepository(ProductVariant::class)->find($subscriptions[0]['subscription']);
}
}
}
}
if (!empty($subscriptions) && $defaultProductVariant != null)
{
$landingPrice = true;
}
$parameters = [
'subscriptionForDefaultPrice' => $subscriptions,
'defaultProductVariant' => $defaultProductVariant,
'landingPrice' => $landingPrice,
'course' => $course
];
return $this->render('uniqskills/catalogue/course_price.html.twig', $parameters);
}
private function hex2rgba($color, $opacity = false): string
{
$default = 'rgb(0,0,0)';
if(empty($color))
return $default;
if ($color[0] == '#' ) {
$color = substr( $color, 1 );
}
if (strlen($color) == 6) {
$hex = array( $color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5] );
} elseif ( strlen( $color ) == 3 ) {
$hex = array( $color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2] );
} else {
return $default;
}
$rgb = array_map('hexdec', $hex);
if($opacity){
$opacity = str_replace(',','.', $opacity);
if(abs($opacity) > 1)
$opacity = 1.0;
$output = 'rgba('.implode(",",$rgb).','.$opacity.')';
} else {
$output = 'rgb('.implode(",",$rgb).')';
}
return $output;
}
}