<?php
/**
* Created by PhpStorm.
* User: Ronald
* Date: 12/23/2019
* Time: 4:31 PM
*/
namespace App\Controller;
use Api\Entity\Country;
use Api\Entity\State;
use Api\Entity\City;
use Api\Entity\ZipCode;
use App\COREapi\NamingStrategy;
use App\Entity\CustomerAccount;
use App\Entity\Quote;
use App\Entity\QuoteItem;
use App\Entity\User;
use App\GoogleAPI\GoogleApi;
use Doctrine\Persistence\ManagerRegistry;
use JMS\Serializer\Naming\SerializedNameAnnotationStrategy;
use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerBuilder;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Asset\Packages;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
abstract class BaseController extends AbstractController
{
const FORMAT_NUMBER_EXCEL_REPORT ='#,##';
const FORMAT_NUMBER_FLOAT_EXCEL_REPORT ='#,##0.00';
private $error;
private $jmsSerializer;
private $doctrine;
public function __construct(ManagerRegistry $doctrine)
{
$this->doctrine = $doctrine;
}
public function getDoctrine(): ManagerRegistry
{
return $this->doctrine;
}
private function resetSessionVar()
{
//Reset session vars
$this->container->get('session')->set('customerAccountDomain', null);
}
protected function initSessionVar()
{
//Reset session vars
$this->resetSessionVar();
$this->getLogoByDomain();
}
/**
* @return \Symfony\Component\HttpFoundation\RedirectResponse|void
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function getLogoByDomain(){
try{
//Find what logo by the domain (host)
$customerAccountDomain = $this->getDoctrine()->getRepository(CustomerAccount::class)->findCustomerAccountByDomain($_SERVER['SERVER_NAME']);
$this->container->get('session')->set('customerAccountDomain', $customerAccountDomain);
if($user=$this->getUser()){
//Already login
if($customerAccountDomain){
//Check that the customer account for the domain is the same as the user (or its parent) that the one that wants to do login.
if(!$user->getCustomerAccount()->isRelatedWithCustomerAccount($customerAccountDomain)){
//Check if the user has a customer account with a domain OR its parent has a domain
throw new \Exception(User::ERROR_PERMISSION);
}
}
else{
//The domain does not exist or it is OLG
if($user->getCustomerAccount()->getDomain1()){
//Check if the user has a customer account with a domain OR its parent has a domain
throw new \Exception(User::ERROR_PERMISSION);
}
//It is a OLG
}
}
}
catch (\Exception $e){
$this->resetSessionVar();
$this->addFlash('error', $e->getMessage());
//Do logout
return $this->redirectToRoute("app_logout");
}
}
/**
* @param string $fileLocation
* @param string $filename
* @return bool
*/
public function deleteFileDir($fileLocation,$filename)
{
// $fileLocation = $base_dir. '/public/uploads/tempImages/hotels/';
try {
if (!is_dir($fileLocation)) {
throw new \Exception("File location does not exist.");
}
//Remove temp image
$fileToDelete = "$fileLocation/$filename";
if(!file_exists($fileToDelete)) {
throw new \Exception("File does not exist.");
}
if (!unlink($fileToDelete)) {
throw new \Exception("There was a problem deleting the file.");
}
return true;
}
catch (\Exception $e){
$this->addFlash('error', 'The file could not be deleted. '.$e->getMessage());
}
return false;
}
/**
* @param $formImageFile
* @param string $dir
* @return false|string
*/
public function uploadImageDir($formImageFile,$dir){
try {
$validFileTypes = array(
'image/ief',
'image/png',
'image/bmp',
'image/tiff',
'image/jpeg');
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$type = finfo_file($finfo, $formImageFile);
if (!in_array($type, $validFileTypes)) {
throw new \Exception("Invalid file type");
}
$newFilename = random_int(1000, PHP_INT_MAX) . '.' . $formImageFile->guessExtension();
try {
$formImageFile->move(
$dir,
$newFilename
);
} catch (FileException $e) {
$this->addFlash('error', "The image couldn't be upload. Error: " . $e->getMessage());
return false;
}
return $newFilename;
}
catch (\Exception $e) {
$this->addFlash('error', "The image couldn't be upload. Error: " . $e->getMessage());
}
return false;
}
protected function json($data, int $status = 200, array $headers = [], array $moreGroups = []): JsonResponse
{
$this->jmsSerializer = new SerializerBuilder();
$this->jmsSerializer->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new NamingStrategy()));
$this->jmsSerializer = $this->jmsSerializer->build();
$context = new SerializationContext();
$context->setSerializeNull(true);
$context->enableMaxDepthChecks();
$groups = array('Default');
if ($moreGroups) {
if (is_array($moreGroups)) {
foreach ($moreGroups as $gr) {
$groups[] = $gr;
}
} else
$groups[] = $moreGroups;
}
$context->setGroups($groups);
if ($this->container->has('serializer')) {
$json = $this->jmsSerializer->serialize($data, 'json', $context);
return new JsonResponse($json, $status, $headers, true);
}
return new JsonResponse($data, $status, $headers);
}
/**
* Return a simple array with the values without any object.
* @param array
* @return array
*/
public function removeNullElemslOnTheArrayToSearchOnDoctrine($params)
{
if(!$params){
return array();
}
foreach ($params as $key=>$value){
if(is_string($value)){
$value=trim($value);
}
if(is_null($value) || ($value=="") || (empty($value) && ($value!=="0"))){
unset($params[$key]);
}
}
if(!isset($params) || !$params){
return array();
}
return $params;
}
/**
* @param array $params
* @return string
*/
public function excelSearchPath(array $params){
$search="";
foreach($params as $key=>$value){
if($value!="") {
if(is_array($value)){
foreach( $value as $subValue){
$search .= "&" . $key . "[]=" . $subValue;
}
} else {
$search .= "&" . $key . "=" . $value;
}
}
}
if($search){
$search="?".$search;
}
return $search;
}
/**
* @param $url
* @return bool
*/
public function remoteFileExists($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $status === 200 ? true : false;
}
/**
* @param $text
* @param string $filename
*/
public function debugAjax($text,$filename='ajax'){
if(is_array($text)){
$text=print_r($text,true);
}
$text=json_encode($text);
$now = new \DateTime("now");
$logPath = 'C:\wamp64\www\debug\logs\ajax\\';
if(is_dir($logPath))
{
$file = fopen($logPath.$filename.date_format($now, 'Ymd').".txt", "a") or die("Unable to open file!");
$txt = date_format($now, 'Y-m-d H:i:s').' '.$text."\n";
fwrite($file, $txt);
fclose($file);
}
}
/**
* @return \Doctrine\Common\Persistence\ObjectManager|object
*/
function getEntityManagerAPI()
{
return $this->getDoctrine()->getManager("api");
}
/**
* @return bool
*/
function checkAPIDatabaseConnection(){
try {
$em = $this->getEntityManagerAPI();
$em->getConnection()->connect();
if(!$em->getConnection()->isConnected()) {
throw new \Exception("Please, contact IT department. No database connection.");
}
return true;
}
catch (\Exception $e){
$msg=$e->getMessage();
if(strpos($e->getMessage(),'No connection could be made because the target machine actively refused it')){
$msg="Please, contact IT department. No database connection could be made because the server refused it. Check the tunnel connection.";
}
$this->setError($msg, $e->getCode(),$e->getCode(), $e->getTraceAsString());
return false;
}
}
/**
* @param string $msg
* @param string $code
* @param string $errorCode
* @param null $fullErrorResponse
* @internal param array $error
*/
public function setError($msg = 'Something is not Right ', $code = 'no error code', $errorCode = 'X', $fullErrorResponse = null)
{
$this->error['msg'] = ucwords($msg);
$this->error['errorCode'] = $errorCode;
$this->error['code'] = $code;
$this->error['fullErrorResponse'] = $fullErrorResponse;
}
public function getError(){
return $this->error;
}
public function getErrorMsg(){
if($this->error){
return $this->error['msg'];
}
return "";
}
/**
* @param \DateTime $startDate
* @param \DateTime $endDate
* @return false|float|int
*/
public function getDiffDay(\DateTime $startDate,\DateTime $endDate){
$startDate->setTime(0, 0, 0);
$endDate->setTime(0, 0, 0);
//Get total days
$diff = $startDate->diff($endDate);
$days=$diff->days;
if($startDate>$endDate){
return $days*(-1);
}
return $days;
}
/**
* @param \DateTime $date
* @param int $days
* @return \DateTime
* @throws \Exception
*/
public function calculateDate(\DateTime $date, int $days){
if($days<0){
$date->sub(new \DateInterval('P' . $days*(-1) . 'D'));
}
else {
$date->add(new \DateInterval('P' . $days . 'D'));
}
return $date;
}
/**
* @param array $suppliers
* @param array $hotels
* @param QuoteItem $quoteItem
* @return string[]
*/
public function getSupplierInfo(array $suppliers, array $hotels, QuoteItem $quoteItem)
{
$type=$quoteItem->getType();
$supplier =["name"=>"","cityName"=>""];
if ($type) {
switch ($type) {
case 'villa':
case 'activity':
case 'transfer':
case 'carRental':
$vendorId=$quoteItem->getVendorId();
if(key_exists($vendorId,$suppliers)){
$supplier["name"] = $suppliers[$vendorId]["name"];
if(key_exists("cityName",$suppliers[$vendorId])) {
$supplier["cityName"] = $suppliers[$vendorId]["cityName"];
}
}
break;
case 'hotel':
// dd($quoteItem->getIdProduct(),$hotels);
if($quoteItem->isHotelWithDifferentBillingSupplier()){
$vendorId=$quoteItem->getAdditionalInformation()['billing_supplier'];
if(key_exists($vendorId,$suppliers)){
$supplier["name"] = $suppliers[$vendorId]["name"];
if(key_exists("cityName",$suppliers[$vendorId])) {
$supplier["cityName"] = $suppliers[$vendorId]["cityName"];
}
}
}
else {
$vendorId=$quoteItem->getVendorId();
if(key_exists($vendorId,$hotels)){
$supplier["name"] = $hotels[$vendorId]["name"];
if(key_exists("city",$hotels[$vendorId])) {
$supplier["cityName"] = $hotels[$vendorId]["city"];
}
}
}
default:
break;
}
}
return $supplier;
}
protected function getLogoPath(\Symfony\Component\Asset\Packages $assetsManager, Quote $quote){
$customerAccountLogo = "";
if($logoImg = $quote->getCustomerAccount()->getLogo()) {
$customerAccountLogo = $assetsManager->getUrl('uploads/customerAccountLogo/' . $logoImg);
}
// if($this->container && $customerAccountDomain = $this->container->get('session')->get('customerAccountDomain')){
// if($customerAccountDomain->getWebsiteLogo()){
// $logoImg = $customerAccountDomain->getWebsiteLogo();
// $customerAccountLogo = $assetsManager->getUrl('uploads/customerAccountLogo/logoWebsite/' . $logoImg);
// }
// }
if($quote->getCreatedBy() && !$quote->getCreatedBy()->getCustomerAccount()->isOLG()){
$customerAccountDomain=$quote->getCreatedBy()->getCustomerAccount();
$customerAccountDomain = $customerAccountDomain->getMainParentCustomerAccount();
if($logoImg = $customerAccountDomain->getWebsiteLogo()) {
$customerAccountLogo = $assetsManager->getUrl('uploads/customerAccountLogo/logoWebsite/' . $logoImg);
}
}
if($logoImg){
//Log to test path
$path = (new \App\Kernel($_ENV['APP_ENV'],false))->getProjectDir() .'/var/log';
@mkdir($path);
$fileSystem = new Filesystem();
$fileSystem->appendToFile($path . '/voucherLogo.txt', "Customer Account Logo: ".$customerAccountLogo."\n" );
//END Log to test path
//Check if the file exist
if (!$this->remoteFileExists($customerAccountLogo)) {
$customerAccountLogo = "";
}
//Log to test path
$fileSystem->appendToFile($path . '/voucherLogo.txt', "Customer Account Logo (AFTER CHECK IF EXIST): ".$customerAccountLogo."\n" );
//END Log to test path
}
return $customerAccountLogo;
}
/**
* @param Quote $quote
* @param $returnException
* @return bool
* @throws \Exception
*/
public function checkIfGrantedToSeeQuote(Quote $quote,$returnException=true){
//Validation for ALC (A La Carta...). Show his own quotes and/or his team quotes
if(!$this->isGranted("ROLE_VIEW_QUOTE_LIMITED_INFO")){
return true;
}
$user = $this->getUser();
//If he creates the quote and/or he is the owner...
if ($user->getId() == $quote->getCreatedBy()->getId() || ($quote->getOwner() && $user->getId() == $quote->getOwner()->getId()) ) {
return true;
}
//Check his team quotes
$teamQuotes=[];
if($user->getTeam()) {
$teamQuotes=$user->getTeam()->getQuotesOwned();
}
foreach ($teamQuotes as $teamQuote){
if($teamQuote->getId()==$quote->getId()){
return true;
}
}
if($returnException){
throw new \Exception('Unauthorized to see this quote');
}
return false;
}
/**
* @param GoogleApi $googleApi
* @param $object
* @param bool $isAPI
* @return void
*/
public function setAddressFromGoogle(GoogleApi $googleApi,&$object,$isAPI=false){
$addressStr = "";
$objectClass = get_class($object);
if (method_exists($objectClass, 'getAddressLine1')) {
$addressStr = $object->getAddressLine1();
} else if (method_exists($objectClass, 'getAddress')) {
$addressStr = $object->getAddress();
}
if ($addressStr) {
if ($addressArray = $googleApi->getAddressArray($addressStr)) {
$em = $this->getDoctrine()->getManager();
if ($isAPI) {
$em = $this->getEntityManagerAPI();
}
//Reset Values
if(method_exists($object,'setLatitude')){
$object->setLatitude(null);
$object->setLongitude(null);
}
$object->setCountry(null);
$object->setState(null);
$object->setCity(null);
$object->setZipCode(null);
//Find the values for each address field.
if (method_exists($object,'setLatitude') && key_exists('location', $addressArray) && key_exists('lat', $addressArray['location'])) {
if(method_exists($object,'setLatitude')){
$object->setLatitude($addressArray['location']['lat']);
$object->setLongitude($addressArray['location']['lng']);
}
}
if (key_exists('country', $addressArray) && $addressArray['country']) {
$name = ucwords($addressArray['country']);
if (!$country = $em->getRepository($isAPI ? Country::class : \App\Entity\Country::class)->findOneBy(['name' => $name])) {
//Add the country
$country = $isAPI ? new Country() : new \App\Entity\Country();
$country->setName($name);
$em->persist($country);
$em->flush();
}
$object->setCountry($country);
if (key_exists('state', $addressArray) && $addressArray['state']) {
$name = ucwords($addressArray['state']);
if (!$state = $em->getRepository($isAPI ? State::class : \App\Entity\State::class)->findOneBy(['country' => $country->getId(), 'name' => $name])) {
//Add the state
$state = $isAPI ? new State() : new \App\Entity\State();
$state->setCountry($country);
$state->setName($name);
$em->persist($state);
$em->flush();
}
$object->setState($state);
}
if (key_exists('city', $addressArray) && $addressArray['city']) {
$name = ucwords($addressArray['city']);
if ($isAPI) {
if (!$city = $em->getRepository(City::class)->findOneBy(['country' => $country->getId(), 'state' => $state->getId(), 'name' => $name])) {
//Add the city
$city = new City();
$city->setCountry($country);
$city->setState($state);
$city->setName($name);
$em->persist($city);
$em->flush();
}
$object->setCity($city);
} else {
//it is a string
$object->setCity($name);
}
}
}
if (key_exists('zipCode', $addressArray) && $addressArray['zipCode']) {
$zipCodeStr = ucwords($addressArray['zipCode']);
if ($isAPI) {
if (!$zipCode = $em->getRepository(ZipCode::class)->findOneBy(['zipCode' => $zipCodeStr])) {
$zipCode = new ZipCode();
$zipCode->setZipCode($zipCodeStr);
$em->persist($zipCode);
$em->flush();
}
$object->setZipCode($zipCode);
} else {
//it is a string
$object->setZipCode($zipCodeStr);
}
}
}
}
}
/**
* @param string|array $content
* @param string $fileName
* @return \Exception|\Symfony\Component\HttpFoundation\BinaryFileResponse
*/
public function createAndDownloadTxtFile(string|array $content,string $fileName="file.txt")
{
try {
if(is_array($content)){
$content = json_encode($content, JSON_FORCE_OBJECT | JSON_PRETTY_PRINT );
}
$tmpFileName = (new Filesystem())->tempnam(sys_get_temp_dir(), 'sb_');
$tmpFile = fopen($tmpFileName, 'wb+');
if (!\is_resource($tmpFile)) {
throw new \RuntimeException('Unable to create a temporary file.');
}
fwrite($tmpFile, $content);
$mime_type = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $tmpFileName);
$response = $this->file($tmpFileName, $fileName);
$response->headers->set('Content-type', $mime_type);
fclose($tmpFile);
return $response;
}
catch (\Exception $e){
return $e;
}
}
/**
* @param array $contentArray
* @param $zipFileName
* @return \Exception|BinaryFileResponse
*/
public function createZip(array $contentArray,$zipFileName='files.zip'){
try {
$zip = new \ZipArchive();
$zipName = tempnam(sys_get_temp_dir(), 'zip');
$zip->open($zipName, \ZipArchive::CREATE);
foreach ($contentArray as $key=>$content){
if(is_array($content)) {
$content = json_encode($content, JSON_FORCE_OBJECT | JSON_PRETTY_PRINT);
}
$zip->addFromString($key, $content);
}
$zip->close();
$response = new BinaryFileResponse($zipName);
$response->headers->set('Content-Type', 'application/zip');
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $zipFileName);
return $response;
}
catch (\Exception $e){
return $e;
}
}
/**
* Check that can see his children (This case is for GTN)
* @param CustomerAccount $customerAccount
* @return bool
*/
protected function isCustomerAccountHostUser(CustomerAccount $customerAccount){
// if($this->getUser()->getCustomerAccount()->getId() != $customerAccount->getId()) {
if(!$this->getUser()->getCustomerAccount()->isOlg()) {
//Check that can see his children (This case is for GTN)
if ($this->isGranted('ROLE_CUSTOMER_ACCOUNT_CREATE_HOST')) {
if ($customerAccountDomain = $this->container->get('session')->get('customerAccountDomain')) {
//Check that this account is one of its children
if(!$customerAccount->getId()){
return true;
}
else if ($customerAccountsHierarchy = $this->getDoctrine()->getRepository(CustomerAccount::class)->findCustomerAccountsHierarchy($customerAccount->getId(), false, false)) {
foreach ($customerAccountsHierarchy as $customerAccountHierarchy) {
if ($customerAccountHierarchy->getParentCustomerAccount() && $customerAccountHierarchy->getParentCustomerAccount()->getId() == $customerAccountDomain->getId()) {
return true;
}
}
}
}
}
}
return false;
}
/**
* Check user (This case is for GTN)
* @param CustomerAccount $customerAccount
* @return bool
*/
protected function isUserHost(User $user){
if(!$user->getCustomerAccount()->isOlg()) {
$customerAccount=$user->getCustomerAccount();
if($customerAccount->getDomain1() ||
($customerAccount->getParentCustomerAccount() && $customerAccount->getParentCustomerAccount()->getDomain1())){
return true;
}
}
return false;
}
/**
* Check user is main host (This case is for GTN)
* @param User $user
* @return bool
*/
protected function isUserMainHost(User $user){
if(!$user->getCustomerAccount()->isOlg() ) {
if($customerAccountDomain = $this->container->get('session')->get('customerAccountDomain') ) {
if($user->getCustomerAccount()->getId()==$customerAccountDomain->getId()){
return true;
}
}
}
return false;
}
public function insertArrayAtPosition( $array, $insert, $position ): array
{
$newArray = [];
foreach($array as $key => $val){
if($key == $position){
$newArray[] = $insert;
}
$newArray[] = $val;
}
return $newArray;
}
/**
* @param $getId
* @return false|mixed
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function getCustomerAccountDomain($getId=false)
{
if(!$customerAccount=$this->container->get('session')->get('customerAccountDomain')){
return false;
}
if($getId){
return $customerAccount->getId();
}
return $customerAccount;
}
public function doFilterByCustomerAccount($returnIdsAsString=true)
{
//Check what can see (This case is for GTN)
if($this->getUser()) {
$customerAccount = $this->getUser()->getCustomerAccount();
$isHostCustomerAccountUser=$this->isCustomerAccountHostUser($customerAccount);
}
else{
if(!$customerAccount=$this->container->get('session')->get('customerAccountDomain')){
return false;
}
$isHostCustomerAccountUser=true;
}
if($isHostCustomerAccountUser){
//This case is for GTN
//Filter by Customer account
/**
* @var $customerAccount CustomerAccount
*/
$ids=[];
$ids[]=$customerAccount->getId();
if($childrenCustomerAccounts=$customerAccount->getChildrenCustomerAccounts()){
foreach($childrenCustomerAccounts as $childrenCustomerAccount){
$ids[]=$childrenCustomerAccount->getId();
}
}
if($returnIdsAsString){
return implode(",",$ids);
}
return $ids;
}
//Show everything
return false;
}
public function getLogoDirByHost(Packages $assetsManager){
$logo = $this->getParameter('ovn_logo_directory') . "/overseas-xpress-logo-scondary.png";
if ($customerAccountDomain = $this->container->get('session')->get('customerAccountDomain')) {
//dir to get the logo image
$imgPath = $this->getParameter('customer_account_logo_website_directory')."/".$customerAccountDomain->getWebsiteLogo();
//url to get the logo image
$pathCustomerAccountLogo = $assetsManager->getUrl('uploads/customerAccountLogo/logoWebsite/'.$customerAccountDomain->getWebsiteLogo());
//Check if the file exist
if ($this->remoteFileExists($pathCustomerAccountLogo)) {
$logo = $imgPath;
}
}
return $logo;
}
}