<?php
namespace EADPlataforma\Controller\Website;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use EADPlataforma\Entity\Product;
use EADPlataforma\Entity\ProductPage;
use EADPlataforma\Entity\ProductCoupon;
use EADPlataforma\Entity\ProductOffer;
use EADPlataforma\Entity\ProductSuggestion;
use EADPlataforma\Entity\ProductTeam;
use EADPlataforma\Entity\Category;
use EADPlataforma\Entity\Faq;
use EADPlataforma\Entity\Course;
use EADPlataforma\Entity\CycleItem;
use EADPlataforma\Entity\CourseTeam;
use EADPlataforma\Entity\CourseTestimonial;
use EADPlataforma\Entity\Lesson;
use EADPlataforma\Entity\LessonModule;
use EADPlataforma\Entity\LessonXLibrary;
use EADPlataforma\Entity\Exam;
use EADPlataforma\Entity\Enrollment;
use EADPlataforma\Entity\User;
use EADPlataforma\Entity\UserSubscription;
use EADPlataforma\Entity\UserCard;
use EADPlataforma\Entity\UserCheckoutInfo;
use EADPlataforma\Entity\Library;
use EADPlataforma\Enum\CourseEnum;
use EADPlataforma\Enum\CourseCertificateEnum;
use EADPlataforma\Enum\EnrollmentEnum;
use EADPlataforma\Enum\ProductEnum;
use EADPlataforma\Enum\ProductCouponEnum;
use EADPlataforma\Enum\ProductOfferEnum;
use EADPlataforma\Enum\ProductPageEnum;
use EADPlataforma\Enum\ProductSuggestionEnum;
use EADPlataforma\Enum\CategoryEnum;
use EADPlataforma\Enum\UserCardEnum;
use EADPlataforma\Enum\UserCheckoutInfoEnum;
use EADPlataforma\Enum\TagsMarketingEnum;
use EADPlataforma\Enum\ProductOpportunityEnum;
use EADPlataforma\Enum\ErrorEnum;
use EADPlataforma\Util\StringUtil;
/**
* @Route(
* schemes = {"http|https"}
* )
* @Cache(
* maxage = "0",
* smaxage = "0",
* expires = "now",
* public = false
* )
*/
class ProductController extends AbstractWebsiteController {
private $searchLimit = 6;
private $testimonialLimit = 9;
/**
* @Route(
* path = "/products",
* name = "productListSearch",
* methods = {"GET"},
* )
*/
public function getProductSearch(Request $request) {
$poRepository = $this->em->getRepository(ProductOffer::class);
$infoOffer = $poRepository->getPublicStoreInfo();
if(!$infoOffer->hasProducts){
return $this->redirectToRoute('notFound');
}
$pixelService = $this->generalService->getService('Marketing\\PixelService');
$pixelService->sendConversion('Search');
$search = $request->get('search');
$types = [
ProductEnum::SUBSCRIPTION => (object)[ "items" => [], "total" => 0 ],
ProductEnum::COURSE => (object)[ "items" => [], "total" => 0 ],
ProductEnum::COMBO => (object)[ "items" => [], "total" => 0 ],
ProductEnum::LIVE => (object)[ "items" => [], "total" => 0 ],
];
foreach ($types as $type => $objType) {
$objType->items = $poRepository->getPublicProductOffers([
"type" => $type,
"search" => $search,
"limit" => $this->searchLimit
]);
$objType->total = $poRepository->countPublicProductOffers(
$type,
null,
$search
);
$types[$type] = $objType;
}
$this->data['search'] = $search;
$dataCourse = (object)[
"enum" => ProductEnum::COURSE,
"name" => $this->configuration->getLanguage('courses', 'product'),
"ico" => "book",
"route" => "productListCourses",
"items" => $types[ProductEnum::COURSE]->items,
"total" => $types[ProductEnum::COURSE]->total
];
$dataPlan = (object)[
"enum" => ProductEnum::SUBSCRIPTION,
"name" => $this->configuration->getLanguage('plans', 'product'),
"ico" => "bookmark",
"route" => "productListPlans",
"items" => $types[ProductEnum::SUBSCRIPTION]->items,
"total" => $types[ProductEnum::SUBSCRIPTION]->total
];
$dataCombo = (object)[
"enum" => ProductEnum::COMBO,
"name" => $this->configuration->getLanguage('combos', 'product'),
"ico" => "package",
"route" => "productListCombos",
"items" => $types[ProductEnum::COMBO]->items,
"total" => $types[ProductEnum::COMBO]->total
];
$dataLive = (object)[
"enum" => ProductEnum::LIVE,
"name" => $this->configuration->getLanguage('lives', 'product'),
"ico" => "package",
"route" => "productListLives",
"items" => $types[ProductEnum::LIVE]->items,
"total" => $types[ProductEnum::LIVE]->total
];
$this->data['hasResult'] = ProductEnum::YES;
if(
empty($types[ProductEnum::COURSE]->items) &&
empty($types[ProductEnum::SUBSCRIPTION]->items) &&
empty($types[ProductEnum::COMBO]->items) &&
empty($types[ProductEnum::LIVE]->items)
){
$this->data['hasResult'] = ProductEnum::NO;
}
$dataSearch = [ $dataCourse, $dataPlan, $dataCombo, $dataLive ];
$this->data['dataSearch'] = $dataSearch;
return $this->renderEAD('product/product-results.html.twig');
}
/**
* @Route(
* path = "/products/order/{couponKey}",
* name = "productListSearchOrder",
* methods = {"POST"},
* defaults = { "couponKey": null }
* )
*/
public function getProductSearchOrder(Request $request) {
$this->requestUtil->setRequest($request)->setData();
$search = $this->requestUtil->getField('search');
$idCategory = $this->requestUtil->getField('category');
$type = $this->requestUtil->getField('type');
$order = $this->requestUtil->getField('order');
$order = ($order === '') ? null : $order;
$offset = $this->requestUtil->getField('offset');
$couponKey = $request->get('couponKey');
$hasModule = $this->configuration->isModuleActive("product_coupon_module");
$enrollmentService = $this->generalService->getService('EnrollmentService');
$pcRepository = $this->em->getRepository(ProductCoupon::class);
$poRepository = $this->em->getRepository(ProductOffer::class);
$infoOffer = $poRepository->getPublicStoreInfo();
if(!$infoOffer->hasProducts){
return $this->redirectToRoute('notFound');
}
$category = null;
if ($idCategory !== null) {
$categoryRepository = $this->em->getRepository(Category::class);
$category = $categoryRepository->findOneBy([
"deleted" => CategoryEnum::ITEM_NO_DELETED,
"status" => CategoryEnum::PUBLISHED,
"id" => $idCategory,
]);
};
$results = $poRepository->getPublicProductOffers([
"type" => $type,
"category" => ($category ? $category->getId() : null),
"search" => $search,
"limit" => $this->searchLimit,
"order" => $order,
"offset" => $offset
]);
$productCoupon = null;
if($hasModule && $category){
$productCoupon = $pcRepository->findValidProductCouponByCategory(
$couponKey,
$category
);
}
$this->data['productCoupon'] = $productCoupon;
if($productCoupon){
foreach ($results as $key => $productOffer) {
$amount = $productOffer->getPriceReal();
$amount = $pcRepository->applyDiscount($productCoupon, $amount);
if($amount > 0){
$productOffer->setPriceRealCopy($amount);
}else{
if($this->user){
$productCoupon->setUsageNumber(
$productCoupon->getUsageNumber() + 1
);
$this->em->flush();
$enrollmentService->setOrigin(EnrollmentEnum::ORIGIN_COUPOM);
$enrollmentService->setCouponKey($couponKey);
$enrollmentService->enrollUserByProduct(
$this->user,
$productOffer->getProduct()
);
}else{
$hash = base64_encode($request->getUri());
$url = $this->generalService->generateUrl('login', [
"hash" => $hash
]);
$redirectResponse = new RedirectResponse($url);
$redirectResponse->headers->set('Content-Type', 'text/html');
$redirectResponse->send();
exit;
}
}
}
}
$this->data['items'] = $results;
return $this->renderEAD('product/product-results-items.html.twig');
}
/**
* @Route(
* path = "/product/suggestion",
* name = "productListSuggestionSearch",
* methods = {"GET"},
* )
*/
public function getProductSuggestionSearch(Request $request) {
$search = $request->get('search');
$poRepository = $this->em->getRepository(ProductOffer::class);
$infoOffer = $poRepository->getPublicStoreInfo();
if(!$infoOffer->hasProducts){
return $this->eadResponse(null, ErrorEnum::ACTION_INVALID);
}
$data = $poRepository->getPublicProductOffersSimply(
null,
null,
$search,
5
);
$typeRoute = [
ProductEnum::COURSE => 'productDetailCourse',
ProductEnum::COMBO => 'productDetailCombo',
ProductEnum::SUBSCRIPTION => 'productDetailPlan',
];
$productTypeTextArr = [
ProductEnum::COURSE => 'curso',
ProductEnum::COMBO => 'combo',
ProductEnum::SUBSCRIPTION => 'plano',
];
$aux = [
'firstLink' => null,
'items' => [],
];
foreach ($data as $key => $value) {
$value = (object)$value;
if(
!empty($typeRoute[$value->type]) &&
!empty($productTypeTextArr[$value->type])
){
$value->offerLink = $value->externalPage;
if(empty($value->externalPage)){
$params = [
"type" => $productTypeTextArr[$value->type],
"slug" => $value->productLink
];
$value->offerLink = $this->generateUrl(
$typeRoute[$value->type],
$params
);
}
$aux['items'][$key] = $value;
}
}
$aux['firstLink'] = "{$this->generateUrl('productListSearch')}?search={$search}";
return $this->eadResponse($aux);
}
/**
* @Route(
* path = "/{type}",
* name = "productListCourses",
* methods = {"GET"},
* requirements = {"type"="cursos|courses"}
* )
*/
public function getProductCourse(Request $request) {
$poRepository = $this->em->getRepository(ProductOffer::class);
$infoOffer = $poRepository->getPublicStoreInfo();
if(!$infoOffer->hasProducts){
return $this->redirectToRoute('notFound');
}
$productOffers = $poRepository->getPublicProductOffers([
"type" => ProductEnum::COURSE
]);
if(empty($productOffers)){
return $this->redirectToRoute('notFound');
}
$this->data['productOffers'] = $productOffers;
$this->data['title'] = $this->configuration->getLanguage('courses', 'product');
return $this->renderEAD('product/product-list.html.twig');
}
/**
* @Route(
* path = "/combos",
* name = "productListCombos",
* methods = {"GET"},
* )
*/
public function getProductCombo(Request $request) {
$poRepository = $this->em->getRepository(ProductOffer::class);
$infoOffer = $poRepository->getPublicStoreInfo();
if(!$infoOffer->hasProducts){
return $this->redirectToRoute('notFound');
}
$productOffers = $poRepository->getPublicProductOffers([
"type" => ProductEnum::COMBO
]);
if(empty($productOffers)){
return $this->redirectToRoute('notFound');
}
$this->data['productOffers'] = $productOffers;
$this->data['title'] = "Combos";
return $this->renderEAD('product/product-list.html.twig');
}
/**
* @Route(
* path = "/{type}",
* name = "productListPlans",
* methods = {"GET"},
* requirements = {"type"="planos|plans"}
* )
*/
public function getProductPlan(Request $request) {
if(!$this->configuration->isModuleActive('product_subscription_module')){
return $this->redirectToRoute('notFound');
}
$poRepository = $this->em->getRepository(ProductOffer::class);
$infoOffer = $poRepository->getPublicStoreInfo();
if(!$infoOffer->hasProducts){
return $this->redirectToRoute('notFound');
}
$planProductOffers = $poRepository->getPublicProductOffers([
"type" => ProductEnum::SUBSCRIPTION
]);
if(empty($planProductOffers)){
return $this->redirectToRoute('notFound');
}
$lMRepository = $this->em->getRepository(LessonModule::class);
$lessonRepository = $this->em->getRepository(Lesson::class);
$examRepository = $this->em->getRepository(Exam::class);
foreach ($planProductOffers as $key => $planProductOffer) {
$planProduct = $planProductOffer->getProduct();
$lmNumber = $lMRepository->getLessonModuleNumberByProduct($planProduct);
$planProduct->lessonModuleNumber = $lmNumber;
$planProduct->lessonNumber = $lessonRepository->getLessonNumberByProduct(
$planProduct
);
$planProduct->examNumber = $examRepository->getExamNumberByProduct(
$planProduct
);
$planProductOffer->setProduct($planProduct);
$planProductOffers[$key] = $planProductOffer;
}
$this->data['planProductOffers'] = $planProductOffers;
return $this->renderEAD('product/product-plan-list.html.twig');
}
/**
* @Route(
* path = "/{type}/{slug}/{couponKey}",
* name = "productListCategory",
* methods = {"GET"},
* defaults = { "couponKey": null },
* requirements = {"type"="cursos|courses|planos|plans|combos|produtos|products"}
* )
*/
public function getByProductCategory(Request $request) {
$limit = 6;
$hasModule = $this->configuration->isModuleActive("product_coupon_module");
$enrollmentService = $this->generalService->getService('EnrollmentService');
$poRepository = $this->em->getRepository(ProductOffer::class);
$categoryRepository = $this->em->getRepository(Category::class);
$pcRepository = $this->em->getRepository(ProductCoupon::class);
$infoOffer = $poRepository->getPublicStoreInfo();
if(!$infoOffer->hasProducts){
return $this->redirectToRoute('notFound');
}
$couponKey = $request->get('couponKey');
$category = $categoryRepository->findOneBy([
"deleted" => CategoryEnum::ITEM_NO_DELETED,
"status" => CategoryEnum::PUBLISHED,
"slug" => $request->get('slug'),
]);
if(!$category){
return $this->redirectToRoute('notFound');
}
$productCoupon = null;
if($hasModule){
$productCoupon = $pcRepository->findValidProductCouponByCategory(
$couponKey,
$category
);
}
$this->data['productCoupon'] = $productCoupon;
$types = [
ProductEnum::SUBSCRIPTION => (object)[ "items" => [], "total" => 0 ],
ProductEnum::COURSE => (object)[ "items" => [], "total" => 0 ],
ProductEnum::COMBO => (object)[ "items" => [], "total" => 0 ],
ProductEnum::LIVE => (object)[ "items" => [], "total" => 0 ],
];
foreach ($types as $type => $objType) {
$objType->items = $poRepository->getPublicProductOffers([
"type" => $type,
"category" => ($category ? $category->getId() : null),
"limit" => $this->searchLimit
]);
if($productCoupon){
foreach ($objType->items as $key => $productOffer) {
$amount = $productOffer->getPriceReal();
$amount = $pcRepository->applyDiscount($productCoupon, $amount);
if($amount > 0){
$productOffer->setPriceRealCopy($amount);
}else{
if($this->user){
$productCoupon->setUsageNumber(
$productCoupon->getUsageNumber() + 1
);
$this->em->flush();
$enrollmentService->setOrigin(EnrollmentEnum::ORIGIN_COUPOM);
$enrollmentService->setCouponKey($couponKey);
$enrollmentService->enrollUserByProduct(
$this->user,
$productOffer->getProduct()
);
}else{
$hash = base64_encode($request->getUri());
$url = $this->generalService->generateUrl('login', [ "hash" => $hash ]);
$redirectResponse = new RedirectResponse($url);
$redirectResponse->headers->set('Content-Type', 'text/html');
$redirectResponse->send();
exit;
}
}
}
}
$objType->total = $poRepository->countPublicProductOffers(
$type,
$category
);
$types[$type] = $objType;
}
$this->data['category'] = $category;
$dataCourse = (object)[
"enum" => ProductEnum::COURSE,
"name" => "Cursos",
"ico" => "book",
"route" => "productListCourses",
"items" => $types[ProductEnum::COURSE]->items,
"total" => $types[ProductEnum::COURSE]->total
];
$dataPlan = (object)[
"enum" => ProductEnum::SUBSCRIPTION,
"name" => "Planos",
"ico" => "bookmark",
"route" => "productListPlans",
"items" => $types[ProductEnum::SUBSCRIPTION]->items,
"total" => $types[ProductEnum::SUBSCRIPTION]->total
];
$dataCombo = (object)[
"enum" => ProductEnum::COMBO,
"name" => "Combos",
"ico" => "package",
"route" => "productListCombos",
"items" => $types[ProductEnum::COMBO]->items,
"total" => $types[ProductEnum::COMBO]->total
];
$dataLive = (object)[
"enum" => ProductEnum::LIVE,
"name" => "Lives",
"ico" => "package",
"route" => "productListLives",
"items" => $types[ProductEnum::LIVE]->items,
"total" => $types[ProductEnum::LIVE]->total
];
$this->data['hasResult'] = ProductEnum::YES;
if(
empty($types[ProductEnum::COURSE]->items) &&
empty($types[ProductEnum::SUBSCRIPTION]->items) &&
empty($types[ProductEnum::COMBO]->items) &&
empty($types[ProductEnum::LIVE]->items)
){
$this->data['hasResult'] = ProductEnum::NO;
}
$dataSearch = [ $dataCourse, $dataPlan, $dataCombo, $dataLive ];
$this->data['dataSearch'] = $dataSearch;
$this->data['search'] = '';
return $this->renderEAD('product/product-results.html.twig');
}
/**
* @Route(
* path = "/{type}/{slug}/{offerHash}",
* name = "productDetailCourse",
* methods = {"GET"},
* defaults = { "offerHash": null },
* requirements = {"type"="curso|course"}
* )
*/
public function getProductCourseDetailPage(Request $request) {
$this->requestUtil->setRequest($request)->setData();
$utmsUrl = http_build_query($this->requestUtil->getData());
$this->data['utmsUrl'] = $utmsUrl;
$slug = $request->get('slug');
$type = $request->get('type');
$offerHash = $request->get('offerHash');
$couponKey = $request->get('coupon');
$pageId = $request->get('page');
$productType = ProductEnum::COURSE;
$poRepository = $this->em->getRepository(ProductOffer::class);
$productOffer = $poRepository->getProductBySlug(
$slug,
$productType,
$offerHash
);
if(!$productOffer){
$productOffer = $poRepository->getProductBySlug(
$slug,
$productType
);
$couponKey = $offerHash;
if(!$productOffer){
return $this->redirectToRoute('notFound');
}
}
$product = $productOffer->getProduct();
if($product->getType() != $productType){
return $this->redirectToRoute('notFound');
}
$productOffer = $poRepository->returnProductOfferOrProductNextClean($productOffer);
$productPage = $productOffer->getProductPage();
if(!empty($pageId) && $this->user){
$permission = $this->userPermissionUtil->getPermission("product", "see");
if(!$this->userPermissionUtil->isLow($permission)){
$productPage = $this->em->getRepository(ProductPage::class)->find($pageId);
}
}
if(!$productPage){
return $this->redirectToRoute('notFound');
}
$externalPage = $productPage->getExternalPage();
$externalPageLink = $productPage->getExternalPageLink();
if($externalPage == ProductEnum::YES && !empty($externalPageLink)){
return $this->redirect($externalPageLink, 301);
}
$this->data['productPage'] = $productPage;
$productRelateds = $product->getProductRelated();
$courseRepository = $this->em->getRepository(Course::class);
$courses = $courseRepository->getCoursesByProduct($product->getId());
$this->data['formName'] = "formFastUserRegister";
$this->data['accessPeriod'] = null;
$this->data['lifetimePeriod'] = CourseEnum::NO;
$this->data['support'] = CourseEnum::NO;
$this->data['supportPeriod'] = null;
$this->data['lifetimeSupport'] = CourseEnum::NO;
$this->data['certificate'] = CourseEnum::NO;
$this->data['generateCertificate'] = CourseCertificateEnum::NO;
$this->data['lessonModules'] = [];
$this->data['couponKey'] = $couponKey;
$this->data['couponKeyValid'] = false;
$this->data['productCoupon'] = null;
$hasModule = $this->configuration->isModuleActive("product_coupon_module");
$enrollmentService = $this->generalService->getService('EnrollmentService');
$productRepository = $this->em->getRepository(Product::class);
$productRepository->saveProductInCache($product);
$pcRepository = $this->em->getRepository(ProductCoupon::class);
$this->data['productOfferCouponTotal'] = $pcRepository->countPublicCouponByProductOffer(
$productOffer
);
if(!empty($couponKey) && $hasModule){
$productCoupon = $pcRepository->findValidProductCouponByProductOffer(
$couponKey,
$productOffer
);
if($productCoupon){
$amount = $productOffer->getPriceReal();
$amount = $pcRepository->applyDiscount($productCoupon, $amount);
if($amount > 0){
$this->data['productCoupon'] = $productCoupon;
$this->data['couponKeyValid'] = true;
$productOffer->setPriceRealCopy($amount);
}else{
if($this->user){
$productCoupon->setUsageNumber(
$productCoupon->getUsageNumber() + 1
);
$this->em->flush();
$enrollmentService->setOrigin(EnrollmentEnum::ORIGIN_COUPOM);
$enrollmentService->setCouponKey($couponKey);
$enrollmentService->enrollUserByProduct(
$this->user,
$productOffer->getProduct()
);
}else{
$params = [
"poID" => $productOffer->getId(),
"pcID" => $productCoupon->getId(),
];
return $this->redirectToRoute('cartAdd', $params);
}
}
}
}
$psRepository = $this->em->getRepository(ProductSuggestion::class);
$productOfferSuggestions = $psRepository->getProductSuggestionsByOfferOrigin(
$productOffer,
ProductSuggestionEnum::EXECUTE_IN_PRODUCT_PAGE
);
$productOfferSuggestionsAddCart = $psRepository->getProductSuggestionsByOfferOrigin(
$productOffer,
ProductSuggestionEnum::EXECUTE_ON_ADD_CART
);
$this->data['emptyProductSuggestion'] = true;
if(!empty($productOfferSuggestions) || !empty($productOfferSuggestionsAddCart)){
$this->data['emptyProductSuggestion'] = false;
}
if($this->data['productCoupon'] && $hasModule){
foreach ($productOfferSuggestions as $key => $offerSuggestion) {
$pcSuggestion = $pcRepository->findValidProductCouponByIdAndProductOffer(
$this->data['productCoupon']->getId(),
$offerSuggestion,
true
);
if($pcSuggestion){
$amount = $offerSuggestion->getPriceReal();
$amount = $pcRepository->applyDiscount($pcSuggestion, $amount);
if($amount > 0){
$offerSuggestion->setPriceRealCopy($amount);
}else{
if($this->user){
$pcSuggestion->setUsageNumber(
$pcSuggestion->getUsageNumber() + 1
);
$this->em->flush();
$enrollmentService->setOrigin(EnrollmentEnum::ORIGIN_COUPOM);
$enrollmentService->setCouponKey($couponKey);
$enrollmentService->enrollUserByProduct(
$this->user,
$offerSuggestion->getProduct()
);
}else{
$hash = base64_encode($request->getUri());
$url = $this->generalService->generateUrl('login', [
"hash" => $hash
]);
$redirectResponse = new RedirectResponse($url);
$redirectResponse->headers->set('Content-Type', 'text/html');
$redirectResponse->send();
exit;
}
}
}
$productOfferSuggestions[$key] = $offerSuggestion;
}
}
$this->data['productOfferSuggestions'] = $productOfferSuggestions;
$numberUtil = $this->generalService->getUtil('NumberUtil');
$parcelInfo = $numberUtil->getNumberMaxParcel(
$productOffer->getPriceRealCopy(true),
$poRepository->getInstallmentNumberMax($productOffer),
$poRepository->getFreeInstallment($productOffer),
$productOffer->getSaleOption(),
$productOffer->getTypeCheckout(),
false
);
$this->data['parcelInfo'] = $parcelInfo;
$this->data['useCard'] = $poRepository->produtOfferAllowCard($productOffer);
$this->data['useBill'] = $poRepository->produtOfferAllowBill($productOffer);
$this->data['usePix'] = $poRepository->produtOfferAllowPix($productOffer);
//ProductOffer Related
$productOffersRelateds = $poRepository->getProductRelatedOffers(
$product
);
//Permission to view draft page
if(
$productOffer->getStatus() == ProductOfferEnum::DRAFT ||
$product->getStatus() == ProductEnum::DRAFT
){
$this->checkUserSession($request);
$permission = $this->userPermissionUtil->getPermission("product", "see");
if($this->userPermissionUtil->isLow($permission)){
return $this->redirectToRoute('notFound');
}
$isInTeam = $this->em->getRepository(ProductTeam::class)->userExistInProductTeam(
$product,
$this->user
);
if(!$isInTeam && $this->userPermissionUtil->isMiddle($permission)){
return $this->redirectToRoute('notFound');
}
}
$this->data['productOffer'] = $productOffer;
$this->data['product'] = $product;
//FAQ
$this->data['faqs'] = $this->em->getRepository(Faq::class)->getFaqForProductDetail(
$product
);
//Course Team
$teachers = $this->em->getRepository(User::class)->getUserTeachersFromProduct(
$product
);
$this->data['courseTotal'] = 0;
$this->data['courses'] = $courses;
$this->data['teacherSection'] = (object)[
"teachers" => $teachers,
"isCenterTitle" => false,
"title" => $this->configuration->getLanguage('instructors', 'product'),
"showSubtitle" => false,
"subtitle" => '',
"showBtnToAll" => false,
];
$this->data['productOffersRelatedsSection'] = (object)[
"title" => $this->configuration->getLanguage('related_products', 'product'),
"subtitle" => $this->configuration->getLanguage('extend_your_knowledge', 'product'),
"name" => "product-related",
"items" => $productOffersRelateds,
"background" => false,
"expand" => false,
"slider" => true,
];
$this->data['planCoursesSection'] = (object)[
"title" => $this->configuration->getLanguage('courses_included_plan', 'product'),
"subtitle" => "",
"name" => "product-plan-course",
"items" => $courses,
"background" => true,
"expand" => false,
"slider" => false,
"isCourse" => true,
"itemsTotal" => $this->data['courseTotal']
];
$courseTestimonialRepository = $this->em->getRepository(CourseTestimonial::class);
//Course Stars
$this->data['scoreProduct'] = $courseTestimonialRepository->getScoreByProduct(
$product
);
$this->data['scoreProduct']->splitScore = [
$this->data['scoreProduct']->fiveStar,
$this->data['scoreProduct']->fourStar,
$this->data['scoreProduct']->threeStar,
$this->data['scoreProduct']->twoStar,
$this->data['scoreProduct']->oneStar,
];
//Course Testimonials
$this->data['courseTestimonials'] = $courseTestimonialRepository->getTestimonialApprovedRandom(
$this->testimonialLimit,
$product
);
foreach ($this->data['courseTestimonials'] as $key => $value) {
$value['testimonial'] = StringUtil::encodeStringStatic($value['testimonial']);
$value['userName'] = StringUtil::encodeStringStatic($value['userName']);
$this->data['courseTestimonials'][$key] = $value;
}
//Lesson Module Total
$lessonModuleRepository = $this->em->getRepository(LessonModule::class);
$this->data['lessonModuleTotal'] = $lessonModuleRepository->getLessonModuleNumberByProduct(
$product
);
//Lesson Total
$lessonRepository = $this->em->getRepository(Lesson::class);
$this->data['lessonTotal'] = $lessonRepository->getLessonNumberByProduct(
$product
);
$productOffersSubscriptionAll = [];
$dateLastUpdate = null;
$auxCourses = [];
foreach ($courses as $key => $course) {
if($course->getStatus() == CourseEnum::PUBLISHED){
$lastUpdate = $course->getDateUpdate();
if(empty($dateLastUpdate) || $lastUpdate > $dateLastUpdate){
$dateLastUpdate = $lastUpdate;
}
if($course->getCertificate() == CourseEnum::YES){
$this->data['certificate'] = CourseEnum::YES;
}
$productOffersSubscription = $poRepository->getProductOffersByCourse(
$course,
ProductEnum::SUBSCRIPTION
);
$productOffersSubscriptionAll = array_merge(
$productOffersSubscriptionAll,
$productOffersSubscription
);
$auxCourses[] = $course;
}
}
$this->data['dateLastUpdate'] = $dateLastUpdate;
$this->data['productOffersSubscriptionSection'] = (object)[
"title" => $this->configuration->getLanguage('you_can_expand', 'product'),
"subtitle" => $this->configuration->getLanguage('sign_up_for_a_plan', 'product'),
"name" => "product-subscription-course",
"items" => $productOffersSubscriptionAll,
"background" => true,
"expand" => false,
"slider" => false,
"isCourse" => true,
"itemsTotal" => $this->data['courseTotal']
];
//Sale number limit
$poRepository = $this->em->getRepository(ProductOffer::class);
$this->data['saleLimitRemaining'] = $poRepository->getProductOfferSaleLimitRemaining(
$productOffer
);
//Courses
$this->data['courses'] = $auxCourses;
//Product time total
$this->data['timeTotal'] = $courseRepository->getAllCourseTimeByProduct($product);
//Product files total
$lessonXLibraryRepository = $this->em->getRepository(LessonXLibrary::class);
$this->data['fileTotal'] = $lessonXLibraryRepository->getLessonXLibraryFilesByProduct(
$product
);
$this->data['userSubscriptionTotal'] = 0;
$this->data['enrollmentTotal'] = 0;
$this->data['keyCaptcha'] = $this->createCaptchaKey($request);
if(!empty(count($courses))){
$course = $courses[0];
$enrollmentRepository = $this->em->getRepository(Enrollment::class);
$this->data['enrollmentTotal'] = $enrollmentRepository->countEnrollmentsByCourse(
$course->getId(),
EnrollmentEnum::STATUS_ACTIVE
);
$cycleItemRepository = $this->em->getRepository(CycleItem::class);
$this->data['accessPeriod'] = $course->getSupport();
$accessPeriod = $cycleItemRepository->getPeriodByDay(
$course->getAccessPeriod()
);
$suportPeriod = $cycleItemRepository->getPeriodByDay(
$course->getSupportPeriod()
);
if($accessPeriod){
$this->data['accessPeriod'] = $accessPeriod->getName();
}
if($suportPeriod){
$this->data['supportPeriod'] = $suportPeriod->getName();
}
$this->data['lifetimePeriod'] = $course->getLifetimePeriod();
$this->data['lifetimeSupport'] = $course->getLifetimeSupport();
$this->data['support'] = $course->getSupport();
//Lesson modules and lessons
$lessonModules = $lessonModuleRepository->getLessonModulesByCourse($course);
$lessonRepository = $this->em->getRepository(Lesson::class);
foreach ($lessonModules as $key => $lessonModule) {
$lessonModule->lessons = $lessonRepository->getLessonByLessonModule(
$lessonModule
);
$lessonModule->workloads = $lessonModuleRepository->getLessonModuleTime(
$lessonModule
);
}
$this->data['lessonModules'] = $lessonModules;
}
if($this->user){
$marketingService = $this->generalService->getService(
'Marketing\\MarketingService'
);
$marketingService->setTag(TagsMarketingEnum::TAG_VISITED_COURSE_PAGE);
$marketingService->setTextComplement($product->getTitle());
$marketingService->setUser($this->user);
$marketingService->setProductOffer($productOffer);
$marketingService->setOpportunity(ProductOpportunityEnum::TAG_VISITED_COURSE_PAGE);
$marketingService->send();
}
$pagarMeTransaction = $this->generalService->getService(
'PagarMe\\PagarMeTransaction'
);
$paymentConfig = $this->configuration->getPaymentConfig();
$installmentsOptions = $pagarMeTransaction->calculateInstallments([
'amount' => $productOffer->getPriceRealCopy(true),
'free_installments' => $poRepository->getFreeInstallment($productOffer),
'max_installments' => $parcelInfo->maxInstallments,
'interest_rate' => $paymentConfig->installmentInterest
]);
$this->data['installmentsOptions'] = (array)$installmentsOptions;
$userCards = null;
$userCheckoutInfos = null;
if($this->user){
$userCardRepository = $this->em->getRepository(UserCard::class);
$userCards = $userCardRepository->getValidUserCard();
$userCheckoutInfoRepository = $this->em->getRepository(UserCheckoutInfo::class);
$userCheckoutInfos = $userCheckoutInfoRepository->findBy([
"user" => $this->user->getId(),
"deleted" => UserCheckoutInfoEnum::ITEM_NO_DELETED
], [ "default" => "DESC" ]);
}
$this->data["isOnSale"] = $poRepository->checkProductOfferIsOnSale($productOffer);
$this->data["userCards"] = $userCards;
$this->data["userCheckoutInfos"] = $userCheckoutInfos;
$this->data["productOffers"] = [ $productOffer ];
$credentials = null;
$videoLibrary = $productPage->getLibrary();
if($videoLibrary){
$libraryRepository = $this->em->getRepository(Library::class);
$credentials = $libraryRepository->getVideoCredentials($videoLibrary);
}
$this->data["credentials"] = $credentials;
if($productPage->getType() == ProductPageEnum::TYPE_LAND_PAGE){
$pixelService = $this->generalService->getService('Marketing\\PixelService');
$pixelService->sendConversion('AddToCart', (object)[
"content_ids" => [ $productOffer->getId() ],
"content_name" => $productOffer->getTitle(),
"currency" => $productOffer->getCurrencyCode(),
"value" => $productOffer->getPriceReal(),
]);
if($this->user && $productOffer->getSaleOption() == ProductOfferEnum::FREE){
$enrollmentService = $this->generalService->getService(
'EnrollmentService'
);
$enrollmentService->setOrigin(EnrollmentEnum::ORIGIN_FREE);
$enrollmentService->enrollUserByProduct(
$this->user,
$productOffer->getProduct()
);
}
return $this->renderEAD('product/landingpage/index.html.twig');
}
return $this->renderEAD("product/product-detail.html.twig");
}
/**
* @Route(
* path = "/{type}/{slug}/{offerHash}",
* name = "productDetailPlan",
* methods = {"GET"},
* defaults = { "offerHash": null },
* requirements = {"type"="plano|plan"}
* )
*/
public function getProductPlanDetailPage(Request $request) {
$this->requestUtil->setRequest($request)->setData();
$utmsUrl = http_build_query($this->requestUtil->getData());
$this->data['utmsUrl'] = $utmsUrl;
$slug = $request->get('slug');
$type = $request->get('type');
$offerHash = $request->get('offerHash');
$couponKey = $request->get('coupon');
$pageId = $request->get('page');
$productType = ProductEnum::SUBSCRIPTION;
$productRepository = $this->em->getRepository(Product::class);
$poRepository = $this->em->getRepository(ProductOffer::class);
$poRepository = $this->em->getRepository(ProductOffer::class);
$productOffer = $poRepository->getProductBySlug(
$slug,
$productType,
$offerHash
);
if(!$productOffer){
$productOffer = $poRepository->getProductBySlug(
$slug,
$productType
);
if(!$productOffer){
return $this->redirectToRoute('notFound');
}
$couponKey = $offerHash;
}
if(
(
$productOffer->getDefault() == ProductEnum::NO ||
$productOffer->getSpotlight() == ProductEnum::NO
) && empty($offerHash)
){
$offerHash = $productOffer->getOfferLink();
}
$product = $productOffer->getProduct();
if($product->getType() != $productType){
return $this->redirectToRoute('notFound');
}
$productRelateds = $product->getProductRelated();
$courseRepository = $this->em->getRepository(Course::class);
$courses = $courseRepository->getCoursesByProduct($product->getId());
$monthOffer = $poRepository->getDefaultOrCustomByCycle(
$product,
ProductOfferEnum::CYCLE_MONTHLY,
$offerHash
);
$quarterlyOffer = $poRepository->getDefaultOrCustomByCycle(
$product,
ProductOfferEnum::CYCLE_QUARTERLY,
$offerHash
);
$semiannualOffer = $poRepository->getDefaultOrCustomByCycle(
$product,
ProductOfferEnum::CYCLE_SEMIANNUAL,
$offerHash
);
$yearlyOffer = $poRepository->getDefaultOrCustomByCycle(
$product,
ProductOfferEnum::CYCLE_YEARLY,
$offerHash
);
$biennialOffer = $poRepository->getDefaultOrCustomByCycle(
$product,
ProductOfferEnum::CYCLE_BIENNIAL,
$offerHash
);
$triennialOffer = $poRepository->getDefaultOrCustomByCycle(
$product,
ProductOfferEnum::CYCLE_TRIENNIAL,
$offerHash
);
$weeklyOffer = $poRepository->getDefaultOrCustomByCycle(
$product,
ProductOfferEnum::CYCLE_WEEKLY,
$offerHash
);
$biweeklyOffer = $poRepository->getDefaultOrCustomByCycle(
$product,
ProductOfferEnum::CYCLE_BIWEEKLY,
$offerHash
);
$productOffers = array_filter([
$monthOffer,
$quarterlyOffer,
$semiannualOffer,
$yearlyOffer,
$biennialOffer,
$triennialOffer,
$weeklyOffer,
$biweeklyOffer,
]);
$productOffer = $poRepository->returnProductOfferOrProductNextPlan(
$productOffer,
$productOffers
);
foreach ($productOffers as $key => $productOfferCycle) {
if($productOfferCycle->getPlanCycle() == $productOffer->getPlanCycle()){
$productOffers[$key] = $productOffer;
}
}
$productPage = $productOffer->getProductPage();
if(!empty($pageId) && $this->user){
$permission = $this->userPermissionUtil->getPermission("product", "see");
if(!$this->userPermissionUtil->isLow($permission)){
$productPage = $this->em->getRepository(ProductPage::class)->find($pageId);
}
}
if(!$productPage){
return $this->redirectToRoute('notFound');
}
$externalPage = $productPage->getExternalPage();
$externalPageLink = $productPage->getExternalPageLink();
if($externalPage == ProductEnum::YES && !empty($externalPageLink)){
return $this->redirect($externalPageLink, 301);
}
$this->data['productPage'] = $productPage;
$this->data['formName'] = "formFastUserRegister";
$this->data["productOffer"] = $productOffer;
$this->data['certificate'] = CourseEnum::NO;
$this->data['generateCertificate'] = CourseCertificateEnum::NO;
$this->data['lessonModules'] = [];
$this->data['couponKey'] = $couponKey;
$this->data['couponKeyValid'] = false;
$this->data['productCoupon'] = null;
$productRepository = $this->em->getRepository(Product::class);
$productRepository->saveProductInCache($product);
$pcRepository = $this->em->getRepository(ProductCoupon::class);
$this->data['productOfferCouponTotal'] = $pcRepository->countPublicCouponByProductOffer(
$productOffer
);
if(!empty($couponKey)){
foreach ($productOffers as $key => $productOfferCycle) {
$productCoupon = $pcRepository->findValidProductCouponByProductOffer(
$couponKey,
$productOfferCycle
);
if($productCoupon){
$amount = $productOfferCycle->getPriceReal();
$amount = $pcRepository->applyDiscount($productCoupon, $amount);
if($amount > 0){
$this->data['couponKeyValid'] = true;
if($productOfferCycle->getPlanCycle() == $productOffer->getPlanCycle()){
$productOffer->setPriceRealCopy($amount);
$this->data['productCoupon'] = $productCoupon;
}
$productOfferCycle->setPriceRealCopy($amount);
}
}
}
}
$psRepository = $this->em->getRepository(ProductSuggestion::class);
$productOfferSuggestions = $psRepository->getProductSuggestionsByOfferOrigin(
$productOffer,
ProductSuggestionEnum::EXECUTE_IN_PRODUCT_PAGE
);
$productOfferSuggestionsAddCart = $psRepository->getProductSuggestionsByOfferOrigin(
$productOffer,
ProductSuggestionEnum::EXECUTE_ON_ADD_CART
);
$this->data['productOfferSuggestions'] = $productOfferSuggestions;
$this->data['emptyProductSuggestion'] = true;
if(!empty($productOfferSuggestions) || !empty($productOfferSuggestionsAddCart)){
$this->data['emptyProductSuggestion'] = false;
}
$numberUtil = $this->generalService->getUtil('NumberUtil');
$parcelInfo = $numberUtil->getNumberMaxParcel(
$productOffer->getPriceRealCopy(true),
$poRepository->getInstallmentNumberMax($productOffer),
$poRepository->getFreeInstallment($productOffer),
$productOffer->getSaleOption(),
$productOffer->getTypeCheckout(),
false
);
$this->data["productOffers"] = $productOffers;
$this->data['parcelInfo'] = $parcelInfo;
$this->data['useCard'] = $poRepository->produtOfferAllowCard($productOffer);
$this->data['useBill'] = $poRepository->produtOfferAllowBill($productOffer);
$this->data['usePix'] = $poRepository->produtOfferAllowPix($productOffer);
//ProductOffer Related
$productOffersRelateds = $poRepository->getProductRelatedOffers(
$product
);
//Permission to view draft page
if($product->getStatus() == ProductEnum::DRAFT){
$this->checkUserSession($request);
$permission = $this->userPermissionUtil->getPermission("product", "see");
if($this->userPermissionUtil->isLow($permission)){
return $this->redirectToRoute('notFound');
}
$isInTeam = $this->em->getRepository(ProductTeam::class)->userExistInProductTeam(
$product,
$this->user
);
if(!$isInTeam && $this->userPermissionUtil->isMiddle($permission)){
return $this->redirectToRoute('notFound');
}
}
$this->data['product'] = $product;
//FAQ
$this->data['faqs'] = $this->em->getRepository(Faq::class)->getFaqForProductDetail(
$product
);
//Course Team
$teachers = $this->em->getRepository(User::class)->getUserTeachersFromProduct(
$product
);
//Product total
$this->data['courseTotal'] = $courseRepository->getPublishedCourseNumberByProduct(
$product->getId()
);
$this->data['teacherSection'] = (object)[
"teachers" => $teachers,
"isCenterTitle" => false,
"title" => $this->configuration->getLanguage('instructors', 'product'),
"showSubtitle" => false,
"subtitle" => '',
"showBtnToAll" => false,
];
$this->data['productOffersRelatedsSection'] = (object)[
"title" => $this->configuration->getLanguage('related_courses', 'product'),
"subtitle" => $this->configuration->getLanguage('extend_your_knowledge', 'product'),
"name" => "product-related",
"items" => $productOffersRelateds,
"background" => true,
"expand" => false,
"slider" => true,
];
$this->data['planCoursesSection'] = (object)[
"title" => $this->configuration->getLanguage('courses_included_plan', 'product'),
"subtitle" => "",
"name" => "product-plan-course",
"items" => $courses,
"background" => true,
"expand" => false,
"slider" => false,
"isCourse" => true,
"itemsTotal" => $this->data['courseTotal']
];
$this->data['productOffersSubscriptionSection'] = (object)[
"title" => $this->configuration->getLanguage('you_can_expand', 'product'),
"subtitle" => $this->configuration->getLanguage('sign_up_for_a_plan', 'product'),
"name" => "product-subscription-course",
"items" => [],
"background" => true,
"expand" => false,
"slider" => false,
"isCourse" => true,
"itemsTotal" => $this->data['courseTotal']
];
$courseTestimonialRepository = $this->em->getRepository(CourseTestimonial::class);
//Course Stars
$this->data['scoreProduct'] = $courseTestimonialRepository->getScoreByProduct(
$product
);
$this->data['scoreProduct']->splitScore = [
$this->data['scoreProduct']->fiveStar,
$this->data['scoreProduct']->fourStar,
$this->data['scoreProduct']->threeStar,
$this->data['scoreProduct']->twoStar,
$this->data['scoreProduct']->oneStar ,
];
//Course Testimonials
$this->data['courseTestimonials'] = $courseTestimonialRepository->getTestimonialApprovedRandom(
$this->testimonialLimit,
$product
);
foreach ($this->data['courseTestimonials'] as $key => $value) {
$value['testimonial'] = StringUtil::encodeStringStatic($value['testimonial']);
$value['userName'] = StringUtil::encodeStringStatic($value['userName']);
$this->data['courseTestimonials'][$key] = $value;
}
//Lesson Module Total
$lessonModuleRepository = $this->em->getRepository(LessonModule::class);
$this->data['lessonModuleTotal'] = $lessonModuleRepository->getLessonModuleNumberByProduct(
$product
);
//Lesson Total
$lessonRepository = $this->em->getRepository(Lesson::class);
$this->data['lessonTotal'] = $lessonRepository->getLessonNumberByProduct(
$product
);
$dateLastUpdate = null;
$auxCourses = [];
foreach ($courses as $key => $course) {
if($course->getStatus() == CourseEnum::PUBLISHED){
$lastUpdate = $course->getDateUpdate();
if(empty($dateLastUpdate) || $lastUpdate > $dateLastUpdate){
$dateLastUpdate = $lastUpdate;
}
if($course->getCertificate() == CourseEnum::YES){
$this->data['certificate'] = CourseEnum::YES;
}
$auxCourses[] = $course;
}
}
$this->data['dateLastUpdate'] = $dateLastUpdate;
//Courses
$this->data['courses'] = $auxCourses;
$this->data['accessPeriod'] = 0;
$this->data['lifetimePeriod'] = CourseEnum::NO;
$this->data['support'] = CourseEnum::NO;
$this->data['supportPeriod'] = 0;
$this->data['lifetimeSupport'] = CourseEnum::NO;
$this->data['enrollmentTotal'] = 0;
//User Subscription total
$userSubscriptionRepository = $this->em->getRepository(UserSubscription::class);
$this->data['userSubscriptionTotal'] = $userSubscriptionRepository->getUserSubscriptionActiveNumberByProduct(
$product
);
$this->data['keyCaptcha'] = $this->createCaptchaKey($request);
//Product time total
$this->data['timeTotal'] = $courseRepository->getAllCourseTimeByProduct($product);
//Sale number limit
$poRepository = $this->em->getRepository(ProductOffer::class);
$this->data['saleLimitRemaining'] = $poRepository->getProductOfferSaleLimitRemaining($productOffer);
//Product files total
$lessonXLibraryRepository = $this->em->getRepository(LessonXLibrary::class);
$this->data['fileTotal'] = $lessonXLibraryRepository->getLessonXLibraryFilesByProduct(
$product
);
if($this->user){
$marketingService = $this->generalService->getService(
'Marketing\\MarketingService'
);
$marketingService->setTag(TagsMarketingEnum::TAG_VISITED_PAGE);
$marketingService->setTextComplement($product->getTitle());
$marketingService->setUser($this->user);
$marketingService->setProductOffer($productOffer);
$marketingService->setOpportunity(ProductOpportunityEnum::TAG_VISITED_PAGE);
$marketingService->send();
}
$pagarMeTransaction = $this->generalService->getService(
'PagarMe\\PagarMeTransaction'
);
$paymentConfig = $this->configuration->getPaymentConfig();
$installmentsOptions = $pagarMeTransaction->calculateInstallments([
'amount' => $productOffer->getPriceRealCopy(true),
'free_installments' => $poRepository->getFreeInstallment($productOffer),
'max_installments' => $parcelInfo->maxInstallments,
'interest_rate' => $paymentConfig->installmentInterest
]);
$this->data['installmentsOptions'] = (array)$installmentsOptions;
$userCards = null;
$userCheckoutInfos = null;
if($this->user){
$userCardRepository = $this->em->getRepository(UserCard::class);
$userCards = $userCardRepository->getValidUserCard();
$userCheckoutInfoRepository = $this->em->getRepository(UserCheckoutInfo::class);
$userCheckoutInfos = $userCheckoutInfoRepository->findBy([
"user" => $this->user->getId(),
"deleted" => UserCheckoutInfoEnum::ITEM_NO_DELETED
], [ "default" => "DESC" ]);
}
$this->data["isOnSale"] = $poRepository->checkProductOfferIsOnSale($productOffer);
$this->data["userCards"] = $userCards;
$this->data["userCheckoutInfos"] = $userCheckoutInfos;
$credentials = null;
$videoLibrary = $productPage->getLibrary();
if($videoLibrary){
$libraryRepository = $this->em->getRepository(Library::class);
$credentials = $libraryRepository->getVideoCredentials($videoLibrary);
}
$this->data["credentials"] = $credentials;
if($productPage->getType() == ProductPageEnum::TYPE_LAND_PAGE){
$pixelService = $this->generalService->getService('Marketing\\PixelService');
$pixelService->sendConversion('AddToCart', (object)[
"content_ids" => [ $productOffer->getId() ],
"content_name" => $productOffer->getTitle(),
"currency" => $productOffer->getCurrencyCode(),
"value" => $productOffer->getPriceReal(),
]);
return $this->renderEAD('product/landingpage/index.html.twig');
}
return $this->renderEAD("product/product-detail.html.twig");
}
/**
* @Route(
* path = "/{type}/{slug}/{offerHash}",
* name = "productDetailCombo",
* methods = {"GET"},
* defaults = { "offerHash": null },
* requirements = {"type"="combo"}
* )
*/
public function getProductComboDetailPage(Request $request) {
$this->requestUtil->setRequest($request)->setData();
$utmsUrl = http_build_query($this->requestUtil->getData());
$this->data['utmsUrl'] = $utmsUrl;
$slug = $request->get('slug');
$type = $request->get('type');
$offerHash = $request->get('offerHash');
$couponKey = $request->get('coupon');
$pageId = $request->get('page');
$productType = ProductEnum::COMBO;
$poRepository = $this->em->getRepository(ProductOffer::class);
$productOffer = $poRepository->getProductBySlug(
$slug,
$productType,
$offerHash
);
if(!$productOffer){
$productOffer = $poRepository->getProductBySlug(
$slug,
$productType
);
$couponKey = $offerHash;
if(!$productOffer){
return $this->redirectToRoute('notFound');
}
}
$product = $productOffer->getProduct();
if($product->getType() != $productType){
return $this->redirectToRoute('notFound');
}
$productOffer = $poRepository->returnProductOfferOrProductNextClean($productOffer);
$productPage = $productOffer->getProductPage();
if(!empty($pageId) && $this->user){
$permission = $this->userPermissionUtil->getPermission("product", "see");
if(!$this->userPermissionUtil->isLow($permission)){
$productPage = $this->em->getRepository(ProductPage::class)->find($pageId);
}
}
if(!$productPage){
return $this->redirectToRoute('notFound');
}
$externalPage = $productPage->getExternalPage();
$externalPageLink = $productPage->getExternalPageLink();
if($externalPage == ProductEnum::YES && !empty($externalPageLink)){
return $this->redirect($externalPageLink, 301);
}
$this->data['productPage'] = $productPage;
$productRelateds = $product->getProductRelated();
$courseRepository = $this->em->getRepository(Course::class);
$courses = $courseRepository->getCoursesByProduct($product->getId());
$this->data['couponKey'] = $couponKey;
$this->data['couponKeyValid'] = false;
$this->data['productCoupon'] = null;
$productRepository = $this->em->getRepository(Product::class);
$productRepository->saveProductInCache($product);
$pcRepository = $this->em->getRepository(ProductCoupon::class);
$this->data['productOfferCouponTotal'] = $pcRepository->countPublicCouponByProductOffer(
$productOffer
);
$this->data['certificate'] = CourseEnum::NO;
$this->data['generateCertificate'] = CourseCertificateEnum::NO;
if(!empty($couponKey)){
$productCoupon = $pcRepository->findValidProductCouponByProductOffer(
$couponKey,
$productOffer
);
if($productCoupon){
$amount = $productOffer->getPriceReal();
$amount = $pcRepository->applyDiscount($productCoupon, $amount);
if($amount > 0){
$this->data['couponKeyValid'] = true;
$this->data['productCoupon'] = $productCoupon;
$productOffer->setPriceRealCopy($amount);
}else{
if($this->user){
$productCoupon->setUsageNumber($productCoupon->getUsageNumber() + 1);
$this->em->flush();
$enrollmentService = $this->generalService->getService(
'EnrollmentService'
);
$enrollmentService->setOrigin(EnrollmentEnum::ORIGIN_COUPOM);
$enrollmentService->setCouponKey($couponKey);
$enrollmentService->enrollUserByProduct(
$this->user,
$productOffer->getProduct()
);
}else{
$params = [
"poID" => $productOffer->getId(),
"pcID" => $productCoupon->getId(),
];
return $this->redirectToRoute('cartAdd', $params);
}
}
}
}
$numberUtil = $this->generalService->getUtil('NumberUtil');
$parcelInfo = $numberUtil->getNumberMaxParcel(
$productOffer->getPriceRealCopy(true),
$poRepository->getInstallmentNumberMax($productOffer),
$poRepository->getFreeInstallment($productOffer),
$productOffer->getSaleOption(),
$productOffer->getTypeCheckout(),
false
);
$this->data['parcelInfo'] = $parcelInfo;
$this->data['useCard'] = $poRepository->produtOfferAllowCard($productOffer);
$this->data['useBill'] = $poRepository->produtOfferAllowBill($productOffer);
$this->data['usePix'] = $poRepository->produtOfferAllowPix($productOffer);
//ProductOffer Related
$productOffersRelateds = $poRepository->getProductRelatedOffers(
$product
);
//Permission to view draft page
if(
$productOffer->getStatus() == ProductOfferEnum::DRAFT ||
$product->getStatus() == ProductEnum::DRAFT
){
$this->checkUserSession($request);
$permission = $this->userPermissionUtil->getPermission("product", "see");
if($this->userPermissionUtil->isLow($permission)){
return $this->redirectToRoute('notFound');
}
$isInTeam = $this->em->getRepository(ProductTeam::class)->userExistInProductTeam(
$product,
$this->user
);
if(!$isInTeam && $this->userPermissionUtil->isMiddle($permission)){
return $this->redirectToRoute('notFound');
}
}
$this->data['productOffer'] = $productOffer;
$this->data['product'] = $product;
$psRepository = $this->em->getRepository(ProductSuggestion::class);
$productOfferSuggestions = $psRepository->getProductSuggestionsByOfferOrigin(
$productOffer,
ProductSuggestionEnum::EXECUTE_IN_PRODUCT_PAGE
);
$productOfferSuggestionsAddCart = $psRepository->getProductSuggestionsByOfferOrigin(
$productOffer,
ProductSuggestionEnum::EXECUTE_ON_ADD_CART
);
$this->data['productOfferSuggestions'] = $productOfferSuggestions;
$this->data['emptyProductSuggestion'] = true;
if(!empty($productOfferSuggestions) || !empty($productOfferSuggestionsAddCart)){
$this->data['emptyProductSuggestion'] = false;
}
//FAQ
$this->data['faqs'] = $this->em->getRepository(Faq::class)->getFaqForProductDetail(
$product
);
//Course Team
$teachers = $this->em->getRepository(User::class)->getUserTeachersFromProduct(
$product
);
//Product total
$this->data['courseTotal'] = $courseRepository->getPublishedCourseNumberByProduct(
$product->getId()
);
$this->data['formName'] = "formFastUserRegister";
$this->data['teacherSection'] = (object)[
"teachers" => $teachers,
"isCenterTitle" => false,
"title" => $this->configuration->getLanguage('instructors', 'product'),
"showSubtitle" => false,
"subtitle" => '',
"showBtnToAll" => false,
];
$this->data['productOffersRelatedsSection'] = (object)[
"title" => $this->configuration->getLanguage('related_courses', 'product'),
"subtitle" => $this->configuration->getLanguage('extend_your_knowledge', 'product'),
"name" => "product-related",
"items" => $productOffersRelateds,
"background" => true,
"expand" => false,
"slider" => true,
];
$this->data['planCoursesSection'] = (object)[
"title" => $this->configuration->getLanguage('courses_included_combo', 'product'),
"subtitle" => "",
"name" => "product-plan-course",
"items" => $courses,
"background" => true,
"expand" => false,
"slider" => false,
"isCourse" => true,
"itemsTotal" => $this->data['courseTotal'],
];
$this->data['productOffersSubscriptionSection'] = (object)[
"title" => $this->configuration->getLanguage('you_can_expand', 'product'),
"subtitle" => $this->configuration->getLanguage('sign_up_for_a_plan', 'product'),
"name" => "product-subscription-course",
"items" => [],
"background" => true,
"expand" => false,
"slider" => false,
"isCourse" => true,
"itemsTotal" => $this->data['courseTotal']
];
$courseTestimonialRepository = $this->em->getRepository(CourseTestimonial::class);
//Course Stars
$this->data['scoreProduct'] = $courseTestimonialRepository->getScoreByProduct(
$product
);
$this->data['scoreProduct']->splitScore = [
$this->data['scoreProduct']->fiveStar,
$this->data['scoreProduct']->fourStar,
$this->data['scoreProduct']->threeStar,
$this->data['scoreProduct']->twoStar,
$this->data['scoreProduct']->oneStar ,
];
//Course Testimonials
$this->data['courseTestimonials'] = $courseTestimonialRepository->getTestimonialApprovedRandom(
$this->testimonialLimit,
$product
);
foreach ($this->data['courseTestimonials'] as $key => $value) {
$value['testimonial'] = StringUtil::encodeStringStatic($value['testimonial']);
$value['userName'] = StringUtil::encodeStringStatic($value['userName']);
$this->data['courseTestimonials'][$key] = $value;
}
//Lesson Module Total
$lessonModuleRepository = $this->em->getRepository(LessonModule::class);
$this->data['lessonModuleTotal'] = $lessonModuleRepository->getLessonModuleNumberByProduct(
$product
);
//Lesson Total
$lessonRepository = $this->em->getRepository(Lesson::class);
$this->data['lessonTotal'] = $lessonRepository->getLessonNumberByProduct(
$product
);
$dateLastUpdate = null;
$auxCourses = [];
foreach ($courses as $key => $course) {
if($course->getStatus() == CourseEnum::PUBLISHED){
$lastUpdate = $course->getDateUpdate();
if(empty($dateLastUpdate) || $lastUpdate > $dateLastUpdate){
$dateLastUpdate = $lastUpdate;
}
if($course->getCertificate() == CourseEnum::YES){
$this->data['certificate'] = CourseEnum::YES;
}
$auxCourses[] = $course;
}
}
$this->data['dateLastUpdate'] = $dateLastUpdate;
//Courses
$this->data['courses'] = $auxCourses;
$this->data['enrollmentTotal'] = 0;
$this->data['userSubscriptionTotal'] = 0;
$this->data['accessPeriod'] = 0;
$this->data['lifetimePeriod'] = CourseEnum::NO;
$this->data['support'] = CourseEnum::NO;
$this->data['supportPeriod'] = 0;
$this->data['lifetimeSupport'] = CourseEnum::NO;
$this->data['lessonModules'] = [];
//Sale number limit
$poRepository = $this->em->getRepository(ProductOffer::class);
$this->data['saleLimitRemaining'] = $poRepository->getProductOfferSaleLimitRemaining($productOffer);
//Product time total
$this->data['timeTotal'] = $courseRepository->getAllCourseTimeByProduct($product);
//Product files total
$lessonXLibraryRepository = $this->em->getRepository(LessonXLibrary::class);
$this->data['fileTotal'] = $lessonXLibraryRepository->getLessonXLibraryFilesByProduct(
$product
);
$this->data['keyCaptcha'] = $this->createCaptchaKey($request);
if($this->user){
$marketingService = $this->generalService->getService(
'Marketing\\MarketingService'
);
$marketingService->setTag(TagsMarketingEnum::TAG_VISITED_PAGE);
$marketingService->setTextComplement($product->getTitle());
$marketingService->setUser($this->user);
$marketingService->setProductOffer($productOffer);
$marketingService->setOpportunity(ProductOpportunityEnum::TAG_VISITED_PAGE);
$marketingService->send();
}
$this->data["productOffers"] = [ $productOffer ];
$pagarMeTransaction = $this->generalService->getService(
'PagarMe\\PagarMeTransaction'
);
$paymentConfig = $this->configuration->getPaymentConfig();
$installmentsOptions = $pagarMeTransaction->calculateInstallments([
'amount' => $productOffer->getPriceRealCopy(true),
'free_installments' => $poRepository->getFreeInstallment($productOffer),
'max_installments' => $parcelInfo->maxInstallments,
'interest_rate' => $paymentConfig->installmentInterest
]);
$this->data['installmentsOptions'] = (array)$installmentsOptions;
$userCards = null;
$userCheckoutInfos = null;
if($this->user){
$userCardRepository = $this->em->getRepository(UserCard::class);
$userCards = $userCardRepository->getValidUserCard();
$userCheckoutInfoRepository = $this->em->getRepository(UserCheckoutInfo::class);
$userCheckoutInfos = $userCheckoutInfoRepository->findBy([
"user" => $this->user->getId(),
"deleted" => UserCheckoutInfoEnum::ITEM_NO_DELETED
], [ "default" => "DESC" ]);
}
$this->data["isOnSale"] = $poRepository->checkProductOfferIsOnSale($productOffer);
$this->data["userCards"] = $userCards;
$this->data["userCheckoutInfos"] = $userCheckoutInfos;
$credentials = null;
$videoLibrary = $productPage->getLibrary();
if($videoLibrary){
$libraryRepository = $this->em->getRepository(Library::class);
$credentials = $libraryRepository->getVideoCredentials($videoLibrary);
}
$this->data["credentials"] = $credentials;
if($productPage->getType() == ProductPageEnum::TYPE_LAND_PAGE){
if($this->user && $productOffer->getSaleOption() == ProductOfferEnum::FREE){
$enrollmentService = $this->generalService->getService(
'EnrollmentService'
);
$enrollmentService->setOrigin(EnrollmentEnum::ORIGIN_FREE);
$enrollmentService->enrollUserByProduct(
$this->user,
$productOffer->getProduct()
);
}
$pixelService = $this->generalService->getService('Marketing\\PixelService');
$pixelService->sendConversion('AddToCart', (object)[
"content_ids" => [ $productOffer->getId() ],
"content_name" => $productOffer->getTitle(),
"currency" => $productOffer->getCurrencyCode(),
"value" => $productOffer->getPriceReal(),
]);
return $this->renderEAD('product/landingpage/index.html.twig');
}
return $this->renderEAD("product/product-detail.html.twig");
}
}