<?php
namespace App\Controller\View\Magazine;
use App\Application\Sonata\MediaBundle\Entity\Media;
use App\Entity\Account\Subscription;
use App\Entity\Magazine\Magazine;
use App\Entity\Magazine\MagazinePage;
use App\Entity\Magazine\TOC;
use App\Entity\Project\Publisher;
use App\Entity\Api\Gatrack;
use App\Entity\Project\PublisherStore;
use App\Service\AdminEngineService;
use App\Service\SerializePageService;
use Exception;
use function PHPSTORM_META\type;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Sabberworm\CSS\Parser;
use Symfony\Component\HttpFoundation\RequestStack;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Cookie;
/**
* @Route("/view/toc")
*/
class TocController extends AbstractController
{
private $requestStack;
private $adminEngine;
private $em;
public function __construct(RequestStack $requestStack, EntityManagerInterface $em, AdminEngineService $adminEngine)
{
$this->requestStack = $requestStack;
$this->adminEngine = $adminEngine;
$this->em = $em;
}
/**
* @Route("/{slug}", methods={"GET"})
*/
public function show(Request $request, $slug)
{
$magazine = $this->getDoctrine()->getRepository(Magazine::class)->findOneBy(['slug'=>$slug, 'paid'=>false]);
if(!$magazine) {
return $this->json(['message' => 'magazine not found'], Response::HTTP_NOT_FOUND);
}
$store = $this->getDoctrine()->getRepository(PublisherStore::class)->findStoreByMag($slug);
if(!$store) {
return $this->json(['message' => 'store not found'], Response::HTTP_NOT_FOUND);
}
$publisherStore = $this->getDoctrine()->getRepository(PublisherStore::class)->findActiveMagInStore($store['slug']);
if(!$publisherStore) {
return $this->json(['message' => 'Publisher store cant find'], Response::HTTP_NOT_FOUND);
}
$store = $this->adminEngine->getRelatedMagazines($publisherStore);
if($request->get('provider') != 'preprod' && $magazine->getPreprod() == true) {
return $this->json(['message' => 'Magazine not found'], Response::HTTP_NOT_FOUND);
}
$pages = $this->getDoctrine()->getRepository(MagazinePage::class)->findBy(['magazine'=>$magazine->getId()], ['position' => 'ASC']);
if(!$pages) {
return $this->json(['message' => 'pages not found'], Response::HTTP_NOT_FOUND);
}
$addcookieHeader = false;
$deviceId = "";
if($slug == "incorsica-70"){
$userid = $request->cookies->get('ga_inc70'); // $user is a string (the userID) or null if there is no cookie.
if (empty($userid)) {
$deviceId = $this->generateIDUtil();
$addcookieHeader = true;
}
else{
$deviceId = $userid;
}
$gatrack = $this->getDoctrine()->getRepository(Gatrack::class)->findOneBy(['deviceId'=>$deviceId]);
$ip = $this->requestStack->getMasterRequest()->getClientIp();
if($ip == 'unknown' || $ip == "127.0.0.1"){
$ip = $_SERVER['REMOTE_ADDR'];
}
$device = $request->headers->get('User-Agent');
if($device){
$device = trim(strtolower($device));
}
$location = "";
$origin = $request->headers->get('origin');
$country = $this->ip_info($ip, "Country");
if($country){
$location = $country;
}
if(!$gatrack){
$gatrack = new Gatrack();
$gatrack->setIp($ip);
$gatrack->setDevice($device);
$gatrack->setLocation($location);
$gatrack->setCount(1);
$gatrack->setDeviceId($deviceId);
$gatrack->setOrigin($origin);
}
else{
$count = $gatrack->getCount();
$gatrack->setDeviceId($deviceId);
$gatrack->setCount($count + 1);
}
try {
$this->em->persist($gatrack);
$this->em->flush();
} catch (\Exception $e) {
// return new JsonResponse(["error" => $e->getMessage()], 500);
}
}
$count = $this->getDoctrine()->getRepository(MagazinePage::class)->countPagesBy($slug);
$magazine->setTotalPages((int) $count);
//$magazineEditedCss = preg_replace('~[\r\n]+~', "", $magazine->getCss());
/*$oParser = new Parser($magazineEditedCss);
$oCss = $oParser->parse();*/
//$magazine->addCssArr($magazineEditedCss);
/*foreach($oCss->getAllDeclarationBlocks() as $oBlock) {
dump($oBlock);die;
dump('-----');die;
}
dump('donzo');die;*/
// $magazine->setCss($magazineEditedCss);
$encoder = new JsonEncoder();
$normalizer = new ObjectNormalizer();
$normalizer->setIgnoredAttributes([
'enabled', 'file', 'subscriptions', 'users', 'root', 'parent', 'lft', 'lvl', 'rgt', 'pages', 'name', 'javascript', 'stylesheet', 'slug', 'version', 'startDate',
'endDate', 'cover', 'publisher', '__initializer__', '__cloner__', '__isInitialized__', 'content', 'template', 'magazine', 'gallery', 'routeName', 'pageAlias', 'createdAt', 'updatedAt', 'collection', 'cssarr', 'css', 'products'
]);
$normalizer2 = new ObjectNormalizer();
$normalizer2->setIgnoredAttributes([
'enabled', 'file', 'subscriptions', 'users', 'root', 'parent', 'lft', 'lvl', 'rgt', 'pages', 'javascript', 'stylesheet', 'slug', 'version', 'startDate',
'endDate', 'cover', 'publisher', '__initializer__', '__cloner__', '__isInitialized__', 'content', 'template', 'magazine', 'galleryHasMedias', 'routeName', 'pageAlias', 'createdAt', 'updatedAt', 'collection', 'cssarr', 'css', 'products'
]);
$normalizer3 = new ObjectNormalizer();
$normalizer3->setIgnoredAttributes([
'enabled', 'file', 'subscriptions', 'users', 'root', 'parent', 'lft', 'lvl', 'rgt', 'toc', 'createdAt', 'updatedAt', 'startedAt', 'user', '__initializer__', '__cloner__', '__isInitialized__', 'pages',
'magazine', 'collection', 'cssarr', 'css', 'products'
]);
$normalizer4 = new ObjectNormalizer();
$normalizer4->setIgnoredAttributes([
'enabled', 'file', 'subscriptions', 'users', 'root', 'parent', 'lft', 'lvl', 'rgt', 'javascript', 'stylesheet', 'slug', 'version', 'startDate',
'endDate', 'cover', 'publisher', '__initializer__', '__cloner__', '__isInitialized__', 'content', 'template', 'magazine', 'gallery', 'routeName', 'pageAlias', 'createdAt', 'updatedAt', 'collection', 'cssarr', 'css', 'products'
]);
$normalizer->setCallbacks([
'thumbnail' => $this->callbackImage(),
'cover' => $this->callbackImage(),
'download' => $this->callbackDownload(),
'publisher' => $this->callbackPublisher(),
'startDate' => $this->callbackDatetime(),
'endDate' => $this->callbackDatetime(),
// 'toc' => $this->callbackToc(),
]);
$normalizer2->setCallbacks([
'thumbnail' => $this->callbackImage(),
'cover' => $this->callbackImage(),
'download' => $this->callbackDownload(),
'publisher' => $this->callbackPublisher(),
'startDate' => $this->callbackDatetime(),
'endDate' => $this->callbackDatetime(),
'gallery' => $this->callbackHasGallery(),
]);
$normalizer3->setCallbacks([
'cover' => $this->callbackImage(),
'thumbnail' => $this->callbackImage(),
'publisher' => $this->callbackPublisher(),
'logo' => $this->callbackImage(),
'download' => $this->callbackDownload(),
'startDate' => $this->callbackDatetime(),
'endDate' => $this->callbackDatetime(),
'imageJson' => $this->callbackJson(),
'bgJson' => $this->callbackJson(),
'productJson' => $this->callbackJson(),
'fontJson' => $this->callbackJson(),
'themeBgColor' => $this->callbackColor(),
'themeTextColor' => $this->callbackColor(),
'contrastBgColor' => $this->callbackColor(),
'contrastTextColor' => $this->callbackColor(),
'mediaIconColor' => $this->callbackColor(),
'opacityColor' => $this->callbackColor(),
'translations' => $this->callbackTranslation(),
]);
$normalizer4->setCallbacks([
'thumbnail' => $this->callbackImage(),
'cover' => $this->callbackImage(),
'download' => $this->callbackDownload(),
'publisher' => $this->callbackPublisher(),
'startDate' => $this->callbackDatetime(),
'endDate' => $this->callbackDatetime(),
]);
$normalizer->setCircularReferenceHandler(function ($object) {
return $object->getId();
});
$normalizer2->setCircularReferenceHandler(function ($object) {
return $object->getId();
});
$normalizer3->setCircularReferenceHandler(function ($object) {
return $object->getId();
});
$toc = $magazine->getToc();
if(!$toc) {
return $this->json(['message' => 'toc not found'], Response::HTTP_NOT_FOUND);
}
$toc = $this->getDoctrine()->getRepository(TOC::class)->findBy(['id' => $toc->getId()], ['position' => 'ASC']);
$serializer = new Serializer(array($normalizer), array($encoder));
$serializer2 = new Serializer(array($normalizer2), array($encoder));
$serializer3 = new Serializer(array($normalizer3), array($encoder));
$serializer4 = new Serializer(array($normalizer4), array($encoder));
//dump($toc);
$jtoc = $serializer->normalize($magazine->getToc(), 'json');
// TODO :: Clean + Fix recursive global change below
usort($jtoc['children'], array($this, 'sortByPos'));
$chapteredArr = [];
foreach ($jtoc['children'] as &$jchild) {
/*if (count($jchild['children']) > 1) {*/
//usort($jchild['children'], array($this, 'sortByPos'));
$chapteredArrchild['title'] = $jchild['title'];
$chapteredArrchild['start'] = $jchild['start'];
$chapteredArrchild['end'] = $jchild['end'];
$chapteredArrchild['thumbnail'] = $jchild['thumbnail'];
$chapteredArrchild['pages'] = [];
array_push($chapteredArr, $chapteredArrchild);
foreach ($jchild['children'] as &$jjchild) {
if (count($jjchild['children']) > 1) {
usort($jjchild['children'], array($this, 'sortByPos'));
}
}
/*}*/
}
function insertArrayAtPosition( $array, $insert, $position, $serializer2 ) {
/*
$array : The initial array i want to modify
$insert : the new array i want to add, eg array('key' => 'value') or array('value')
$position : the position where the new array will be inserted into. Please mind that arrays start at 0
*/
/*dump($serializer2->normalize(array_slice($array, 0, $position, TRUE), 'json'));
dump($serializer2->normalize($insert, 'json'));
dump($serializer2->normalize(array_slice($array, $position, NULL, TRUE), 'json'));
dump('-----------');
dump($serializer2->normalize(array_slice($array, 0, $position, TRUE) + $insert + array_slice($array, $position, NULL, TRUE), 'json'));
dump('===========');*/
return array_slice($array, 0, $position, TRUE) + $insert + array_slice($array, $position, count($array) - 1, TRUE);
}
function insertValueAtPosition($arr, $insertedArray, $position, $serializer2) {
/*dump($position);
dump($serializer2->normalize($arr, 'json'));*/
$i = 0;
$new_array=[];
foreach ($arr as $key => $value) {
if ($i == $position) {
foreach ($insertedArray as $ikey => $ivalue) {
$new_array[$ikey] = $ivalue;
}
}
$new_array[$key] = $value;
$i++;
}
return $new_array;
}
/**
* Reposition an array element by its key.
*
* @param array $array The array being reordered.
* @param string|int $key They key of the element you want to reposition.
* @param int $order The position in the array you want to move the element to. (0 is first)
*
* @throws \Exception
*/
function repositionArrayElement(array &$array, $key, int $order, $insert)
{
array_push($array, $insert);
if(($a = array_search($key, array_keys($array))) === false){
throw new \Exception("The {$key} cannot be found in the given array.");
}
$p1 = array_splice($array, $a, 1);
$p2 = array_splice($array, 0, $order);
$array = array_merge($p2, $p1, $array);
}
//$magazinePageEditedCss = "";
$j = 0;
$prevChaptered = 0;
$singleChapterCount = 0;
$isAdvert = true;
$advertChapterExist = false;
foreach ($pages as $i => $page) {
//if ($i = 7) die;
$isChaptered = false;
/*if($page->getStylesheet() !== null && $page->getStylesheet() !== "") {
// $magazineEditedCss .= "//----- page-". $page->getPosition() ."-----/";
// $magazineEditedCss = $magazineEditedCss . preg_replace('~[\r\n]+~', "", $page->getStylesheet());
if (strlen($magazinePageEditedCss) >= 9000) {
$magazine->addCssArr($magazinePageEditedCss);
$magazinePageEditedCss = "";
}
$magazinePageEditedCss .= "//---- page-". $page->getPosition() ."----/";
$magazinePageEditedCss = $magazinePageEditedCss . preg_replace('~[\r\n]+~', "", $page->getStylesheet());
}*/
if ((int)$page->getPosition() !== 1) { // skip first/cover page
foreach ($chapteredArr as $j => $chapter) {
if (!is_array($chapter))
continue;
if ($chapter instanceof Chapter)
continue;
if (count($chapteredArr) - 1 != (int)$j) {
if (is_array($chapteredArr[$j+1]))
$end = ($chapter['end']) ?: (((int)$chapteredArr[$j + 1]['start'] - 1 < (int)$chapter['start']) ? (int)$chapter['start'] : (int)$chapteredArr[$j + 1]['start'] - 1);
else
$end = ($chapter['end']) ?: (((int)$chapteredArr[$j+1]->start - 1 < (int)$chapter['start']) ? (int)$chapter['start'] : (int)$chapteredArr[$j+1]->start - 1);
} else
$end = ($chapter['end']) ?: count($pages);
if (is_numeric($page->getPageno()) && ((int)$page->getPageno() >= (int)$chapter['start']) && ((int)$page->getPageno() <= (int)$end)) {
array_push($chapteredArr[$j]['pages'], $page);
$isChaptered = true;
$prevChaptered = $j;
$isAdvert = false;
break;
} elseif ($isAdvert) {
// create Advert chapter
if (!$advertChapterExist) {
$advertChapter = new Chapter();
$advertChapter->title = "Advert";
$advertChapterExist = true;
repositionArrayElement($chapteredArr, count($chapteredArr), 1, $advertChapter);
}
array_push($advertChapter->pages, $page);
$isChaptered = true;
break;
}
}
}
if (!$isChaptered) {
$myChapter = new Chapter();
$myChapter->title = ($page->getPosition() === 1)? "Cover" : $page->getName();
$myChapter->start = $page->getPageno();
$myChapter->end = $page->getPageno();
$myChapter->thumbnail = $page->getThumbnail();
array_push($myChapter->pages, $page);
repositionArrayElement($chapteredArr, count($chapteredArr), $prevChaptered + $singleChapterCount, $myChapter);
$singleChapterCount++;
}
}
//$magazine->addCssArr($magazinePageEditedCss);
// TODO :: Fix ^
// $this->orderByPos($jtoc);
$response = $this->json(['detail' => $serializer3->normalize($magazine, 'json'), 'articles' => $jtoc, 'pages' => $serializer2->normalize($pages, 'json'), 'chapter_pages' => $serializer4->normalize($chapteredArr, 'json'), 'affiliated' => $serializer4->normalize($store, 'json')]);
if($addcookieHeader){
$cookie = new Cookie('ga_inc70', $deviceId, (time() + (365 * 24 * 60 * 60)), '/', null, true, false, false, 'None' ); // Expires 1 years
$response->headers->setCookie($cookie);
}
return $response;
}
private function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
$output = NULL;
if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
$ip = $_SERVER["REMOTE_ADDR"];
if ($deep_detect) {
if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
}
$purpose = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
$support = array("country", "countrycode", "state", "region", "city", "location", "address");
$continents = array(
"AF" => "Africa",
"AN" => "Antarctica",
"AS" => "Asia",
"EU" => "Europe",
"OC" => "Australia (Oceania)",
"NA" => "North America",
"SA" => "South America"
);
if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) {
$ipdat = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
if (@strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
switch ($purpose) {
case "location":
$output = array(
"city" => @$ipdat->geoplugin_city,
"state" => @$ipdat->geoplugin_regionName,
"country" => @$ipdat->geoplugin_countryName,
"country_code" => @$ipdat->geoplugin_countryCode,
"continent" => @$continents[strtoupper($ipdat->geoplugin_continentCode)],
"continent_code" => @$ipdat->geoplugin_continentCode
);
break;
case "address":
$address = array($ipdat->geoplugin_countryName);
if (@strlen($ipdat->geoplugin_regionName) >= 1)
$address[] = $ipdat->geoplugin_regionName;
if (@strlen($ipdat->geoplugin_city) >= 1)
$address[] = $ipdat->geoplugin_city;
$output = implode(", ", array_reverse($address));
break;
case "city":
$output = @$ipdat->geoplugin_city;
break;
case "state":
$output = @$ipdat->geoplugin_regionName;
break;
case "region":
$output = @$ipdat->geoplugin_regionName;
break;
case "country":
$output = @$ipdat->geoplugin_countryName;
break;
case "countrycode":
$output = @$ipdat->geoplugin_countryCode;
break;
}
}
}
return $output;
}
private function generateIDUtil() {
return bin2hex(random_bytes(4)) . substr(base_convert(md5(time()), 16,32), 0, 6);;
}
private function callbackImage()
{
$callback = function ($image) {
return $image instanceof Media
? $image->getUrlMethod()
: null;
};
return $callback;
}
private function orderByPos($tg) {
foreach ($tg['children'] as &$jchild) {
if (count($jchild['children']) > 1) {
usort($jchild['children'], array($this, 'sortByPos'));
$this->orderByPos($jchild);
}
}
}
private function sortByPos($a, $b) {
// dump($a);die;
return $a['position'] > $b['position'];
}
private function callbackDownload()
{
$callback = function ($pdf) {
return $pdf instanceof Media
? $pdf->getUrlMethod()
: null;
};
return $callback;
}
private function callbackTranslation()
{
$callback = function ($translations) {
if (!$translations->isEmpty()) {
foreach ($translations as $translation)
$arrtranslations[] = [
$translation->getLocale() => $translation->getSlug(),
];
return $arrtranslations;
}else
return null;
};
return $callback;
}
private function callbackJson()
{
$callback = function ($imageJson) {
if ($imageJson != null)
return json_decode($imageJson, true);
else
return null;
};
return $callback;
}
private function callbackDatetime()
{
$callback = function ($dateTime) {
return $dateTime instanceof \DateTime
? $dateTime->format(\DateTime::ISO8601)
: $dateTime;
};
return $callback;
}
private function callbackHasGallery()
{
$callback = function ($gallery) {
if ($gallery != null)
return true;
else
return null;
};
return $callback;
}
private function callbackColor()
{
$callback = function ($color) {
if ($color != null) {
(strlen($color) === 4) ? list($r, $g, $b) = sscanf($color, "#%1x%1x%1x") : list($r, $g, $b) = sscanf($color, "#%2x%2x%2x");
$color = $r . "," . $g . "," . $b;
} else {
$color = null;
}
return $color;
};
return $callback;
}
private function callbackToc()
{
$callback = function ($toc) {
dump($toc);
return $toc;
};
return $callback;
}
private function callbackPublisher() {
$callback = function ($publisher) {
if ($publisher instanceof Publisher) {
$publisher = [
'name' => $publisher->getName(),
'logo' => ($publisher->getLogo()) ? $publisher->getLogo()->getUrlMethod() : null,
'website' => $publisher->getWebsite(),
'email' => $publisher->getEmail(),
'address' => $publisher->getAddress(),
'phone' => $publisher->getPhone(),
];
} else {
$publisher = null;
}
return $publisher;
};
return $callback;
}
}
class Chapter
{
public $title;
public $start;
public $end;
public $thumbnail;
public $pages = [];
}