<?php
declare(strict_types=1);
namespace App\Manager;
use App\Entity\Local\Icon;
use App\Entity\Local\OrderSeat;
use App\Entity\Local\Response\SeatPlanResponse;
use App\Entity\Local\Response\SetTicketsOnServerResponse;
use App\Entity\Local\SetTicketsForSessionRequest;
use App\Entity\Local\ValueObject\ThirdPartyMemberScheme;
use App\Entity\Vista\DTO\TicketDTO;
use App\Entity\Vista\LoyaltyMember;
use App\Entity\Vista\Order;
use App\Entity\Vista\Row;
use App\Entity\Vista\Seat;
use App\Entity\Vista\SeatPosition;
use App\Entity\Vista\Session;
use App\Entity\Vista\SessionTicketType;
use App\Entity\Vista\Ticket;
use App\Entity\Vista\TicketDetails;
use App\Exceptions\SeatPlanException;
use App\Repository\CinemaAreaCategoryRepository;
use App\Repository\OrderRepositoryInterface;
use App\Repository\SeatPlanRepository;
use App\Repository\TicketRepository;
use App\Security\Security;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\Yaml\Yaml;
use Symfony\Contracts\Translation\TranslatorInterface;
use Psr\Log\LoggerInterface;
use App\Repository\RestrictionsRepository;
use App\Entity\Local\Restrictions;
use App\Repository\Vista\SessionVistaRepository as SessionRepository;
use App\Repository\SeatPlanLocalRepository;
use Exception;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
/**
* @TODO: split in 2-3 services
*/
class SeatPlanManager
{
const FREE_STATUSES = [0, 3, 99];
const FREE_STATUSES_NO_WHEELCHAIR = [0, 99];
const OCCUPIED_STATUSES = [1, 4];
/**
* @var SeatPlanRepository
*/
protected $seatPlanRepository;
/**
* @var array
*/
protected $rowGroups__ = [];
/**
* @var array
*/
protected $rowGroupsSingletons__ = [];
/**
* @var CinemaAreaCategoryRepository
*/
private $cinemaAreaCategoryRepository;
/**
* @var TicketRepository
*/
private $ticketRepository;
/**
* @var Security
*/
private $security;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @var OrderRepositoryInterface
*/
private $orderRepository;
/**
* @var string
*/
private $rootDir;
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var Restrictions
*/
private $restrictions;
/** @var SessionRepository */
private $sessionRepository;
/** @var SeatPlanLocalRepository */
protected $seatPlanLocalRepository;
/** @var SerializerInterface $serializer */
protected $serializer;
/** @var DenormalizerInterface */
protected $normalizer;
public function __construct(
SeatPlanRepository $seatPlanRepository,
OrderRepositoryInterface $orderRepository,
SessionRepository $sessionRepository,
CinemaAreaCategoryRepository $cinemaAreaCategoryRepository,
TicketRepository $ticketRepository,
Security $security,
TranslatorInterface $translator,
string $rootDir,
LoggerInterface $logger,
RestrictionsRepository $restrictionsRepository,
SeatPlanLocalRepository $seatPlanLocalRepository,
DenormalizerInterface $normalizer,
SerializerInterface $serializer
) {
$this->seatPlanRepository = $seatPlanRepository;
$this->cinemaAreaCategoryRepository = $cinemaAreaCategoryRepository;
$this->orderRepository = $orderRepository;
$this->ticketRepository = $ticketRepository;
$this->security = $security;
$this->translator = $translator;
$this->rootDir = $rootDir;
$this->logger = $logger;
$this->restrictions = $restrictionsRepository->findOrCreate();
$this->sessionRepository = $sessionRepository;
$this->seatPlanLocalRepository = $seatPlanLocalRepository;
$this->serializer = $serializer;
$this->normalizer = $normalizer;
}
/**
* @param object &$seatPlanTree
* @param string $cinemaId
*
*/
public function setSeatPlanIcons(object &$seatPlanTree, string $cinemaId)
{
$categories = $this->cinemaAreaCategoryRepository->find($cinemaId);
$icons = $this->cinemaAreaCategoryRepository->getIcons();
foreach ($seatPlanTree->SeatLayoutData->Areas as &$arrea) {
$arrea->SeatsSpace = 0;
$categoryId = null;
if ($category = $categories[intval($arrea->AreaCategoryCode)] ?? []) {
$categoryId = $category ? $category->getAreaCategoryId() : -1;
}
if ($columnIndex = call_user_func(function ($rows) {
$rowFirst = null;
foreach ($rows as $row) {
if ($seats = $row->getSeats()) {
return $seats[0]->getPosition()->getColumnIndex();
}
}
}, $arrea->Rows)) {
error_log(sprintf("%s %s(%s) columnIndex $columnIndex", date('Y-m-d H:i:s'), __METHOD__, __LINE__));
}
foreach ($arrea->Rows as &$row) {
foreach ($row->Seats as &$seat) {
$seat->iconUrl = "";
$seat->iconId = "";
if ($categoryId) {
$seatObj = (new Seat())
->setAreaCategoryCode($arrea->AreaCategoryCode)
->setSeatStyle($seat->SeatStyle)
->setStatus($seat->Status)
->setOriginalStatus($seat->OriginalStatus);
$seatsInGroup = [];
if (is_array($seat->SeatsInGroup)) {
foreach ($seat->SeatsInGroup as $group) {
$seatsInGroup[] = (array) $group;
}
//error_log(sprintf("%s %s(%s) ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . ' seat->SeatsInGroup ' . var_export($seat->SeatsInGroup, true));
}
$seatObj->setSeatsInGroup($seatsInGroup);
$seat->iconId = $this->seatPlanRepository->matcher->getIconId($seatObj, $categoryId);
$seat->improvedIconId = $this->seatPlanRepository->matcher->getImprovedIconId($seatObj, $categoryId);
if (array_key_exists($seat->iconId, $icons)) {
$seat->iconUrl = $icons[$seat->iconId]['imageUrl'];
}
}
$position = $seat->getPosition();
//if (!is_int($position->getColumnIndexVista())) {
//error_log(sprintf("%s %s(%s) ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . $position->getColumnIndex() . ' ' . $position->getColumnIndexVista());
//$position->setColumnIndexVista($position->getColumnIndex());
//$position->setColumnIndexRender($position->getColumnIndex());
//}
}
}
}
}
/**
* @param string $cinemaId
* @param string|null $sessionId
* @param string|null $responseJson
*
* @return SeatPlanResponse
*/
public function getSeatPlan(string $cinemaId, string $sessionId, string $responseJson = null, $applySaved = true): SeatPlanResponse
{
$start = microtime(true);
$categories = $this->cinemaAreaCategoryRepository->find($cinemaId);
$this->logger->info(sprintf("profiling seat selection :: cinemaAreaCategoryRepository->find execution time: %f", microtime(true) - $start));
$start = microtime(true);
[$errorDescription, $rows] = $this->seatPlanRepository->getSeatPlan($cinemaId, $sessionId, $categories);
$this->logger->info(sprintf("profiling seat selection :: seatPlanRepository->getSeatPlan execution time: %f", microtime(true) - $start));
if ($errorDescription) {
$this->logger->error('SeatPlanManager::getSeatPlan() Vista error response: ' . $errorDescription);
}
$seatPlanSaved = '0';
$icons = [];
$start = microtime(true);
$rows = $this->applySaved($rows, $icons, $cinemaId, $sessionId, $applySaved);
$this->logger->info(sprintf("profiling seat selection :: applySaved execution time: %f", microtime(true) - $start));
if ($seatPlanSaved === '0') {
$icons = $this->cinemaAreaCategoryRepository->getIcons();
}
return (new SeatPlanResponse())
->setRows($rows)
->setIcons($icons)
->setRowsMax($this->getMaxRows($rows))
->setError($errorDescription)
->setSeatPlanSaved($seatPlanSaved);
}
private function applySaved($rows, &$icons, $cinemaId, $sessionId, $applySaved)
{
$session = $this->sessionRepository->findOneBy(['sessionId' => $sessionId, 'cinemaId' => $cinemaId]);
$screenNumber = $session->getScreenNumber();
if ($applySaved && $seatPlanJson = $this->seatPlanLocalRepository->findOneBy(['cinemaId' => $cinemaId, 'screenNumber' => $screenNumber])) {
$seatPlanInput = $seatPlanJson->getSeatPlanJson();
$responseJsonObj = json_decode($seatPlanInput);
$rowsMax = $responseJsonObj->rowsMax;
foreach ($responseJsonObj->icons as $icon) {
$icons[] = $this->normalizer->denormalize($icon, Icon::class);
}
$seatPlanSaved = '1';
$rowsSaved = [];
foreach ($responseJsonObj->rows as $rowJson) {
$row = $this->serializer->deserialize(json_encode($rowJson), Row::class, 'json');
$rowsSaved[] = $row;
}
//error_log(sprintf("%s %s(%s) screenNumber $screenNumber cinemaId $cinemaId ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . ' count($rows) ' . count($rows) . ' count($rowsSaved) ' . count($rowsSaved));
error_log(sprintf("%s %s(%s) screenNumber $screenNumber cinemaId $cinemaId ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . ' count($rows) ' . count($rows) . ' count($rowsSaved) ' . count($rowsSaved));
$rows = $this->reservationsToSaved2($rows, $rowsSaved, $rowsMax);
error_log(sprintf("%s %s(%s) screenNumber $screenNumber cinemaId $cinemaId ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . ' count($rows) ' . count($rows) . ' count($rowsSaved) ' . count($rowsSaved));
} else {
$this->setVistaColumns($rows);
}
return $rows;
}
public function getSavedRows($sessionId, $cinemaId, $screenNumber = null)
{
if ($screenNumber == null && ($session = $this->sessionRepository->findOneBy(['sessionId' => $sessionId, 'cinemaId' => $cinemaId]))) {
$screenNumber = $session->getScreenNumber();
}
if ($screenNumber && ($seatPlanJson = $this->seatPlanLocalRepository->findOneBy(['cinemaId' => $cinemaId, 'screenNumber' => $screenNumber]))) {
$seatPlanInput = $seatPlanJson->getSeatPlanJson();
$responseJsonObj = json_decode($seatPlanInput);
$rowsSaved = [];
foreach ($responseJsonObj->rows as $rowJson) {
$row = $this->serializer->deserialize(json_encode($rowJson), Row::class, 'json');
$rowsSaved[] = $row;
}
return $rowsSaved;
}
}
public function setVistaColumns(&$rows)
{
if ($columnIndex = call_user_func(function ($rows) {
$rowFirst = null;
foreach ($rows as $row) {
if ($seats = $row->getSeats()) {
return $seats[0]->getPosition()->getColumnIndex();
}
}
}, $rows)) {
error_log(sprintf("%s %s(%s) columnIndex $columnIndex", date('Y-m-d H:i:s'), __METHOD__, __LINE__));
}
foreach ($rows as &$row) {
foreach ($row->getSeats() as &$seat) {
$position = $seat->getPosition();
if (!is_int($position->getColumnIndexVista())) {
$position->setColumnIndexVista($position->getColumnIndex());
}
if ($position->getColumnIndexRender() === null) {
$position->setColumnIndexRender($position->getColumnIndex());
}
}
}
}
/**
* @param Row[] $seatPlanRows
* @param $cinemaId
*/
public function fillSeatPlanWithIcons($seatPlanRows, $cinemaId)
{
$categories = $this->cinemaAreaCategoryRepository->find($cinemaId);
$this->seatPlanRepository->setIconIds($seatPlanRows, $categories);
}
/**
* @param Row[] $rows
*
* @return int
*/
private function getMaxRows($rows): int
{
$max = 0;
foreach ($rows as $row) {
if ($row && ($columnCount = $row->getColumnCount()) > $max) {
$max = $columnCount;
}
}
return $max;
}
/**
* @param Row[] $seatPlanRows
* @param TicketDTO $query
* @param Order $order
*
* @return array
*/
public function getSeats(array $seatPlanRows, TicketDTO $query, Order $order)
{
$this->logger->info(" ---> entering getSeats <---");
$selectedSeatData = $query->getSeats()[0] ?? [];
$selectedSeat = null;
$selectedCount = 0;
if ($selectedSeatData) {
$this->logger->info(" ---> selectedSeatData available <---");
$selectedSeat = (new Seat())->setPosition($selectedSeatData);
$selectedCount = 0
+ ($query->getNumberOfSeats() ? $query->getNumberOfSeats() : 0)
+ ($query->getNumberOfChildSeats() ? $query->getNumberOfChildSeats() : 0)
+ ($query->getNumberOfReducedSeats() ? $query->getNumberOfReducedSeats() : 0)
+ ($query->getNumberOfFilmBrunchSeats() ? $query->getNumberOfFilmBrunchSeats() : 0)
+ ($query->getNumberOfPackageReducedSeats() ? $query->getNumberOfPackageReducedSeats() : 0)
+ ($query->getNumberOfPackageRegularSeats() ? $query->getNumberOfPackageRegularSeats() : 0)
+ ($query->getNumberOfPackageClubSeats() ? $query->getNumberOfPackageClubSeats() : 0)
+ ($query->getNumberOfPackageChildSeats() ? $query->getNumberOfPackageChildSeats() : 0)
+ ($query->getNumberOfPackageWheelchairSeats() ? $query->getNumberOfPackageWheelchairSeats() : 0)
+ ($query->getNumberOfFilmBrunchChildSeats() ? $query->getNumberOfFilmBrunchChildSeats() : 0);
}
$selection = $this->select(
$seatPlanRows,
$selectedSeat,
$selectedCount,
$order->getSelection()
);
/** @var SeatPosition[] $positions */
//$positions = array_map(function (Seat $item) { return $item->getPosition(); }, $selection);
$positions = array_map(function (Seat &$seat) {
return $seat->getPosition();
}, $selection);
return [
$positions,
$selection,
$selectedSeatData,
];
}
public function setTickets(Order $order, ?Session $session, TicketDTO $query): SetTicketsOnServerResponse
{
// read drive in cinema mapping config
$di_mapping = Yaml::parseFile($this->rootDir . '/config/drive_in_mapping.yml');
$di_map = null;
foreach ($di_mapping as $map) {
if ($session->getCinemaId() === $map['drive_in_cinema_id']) {
$di_map = $map;
break;
}
}
$initSelection = $order->getSelection();
if ($di_map) {
$this->logger->debug('drive in session selected');
$setTicketsOnServerResponse = (new SetTicketsOnServerResponse())->setOrder($order);
/** @var TicketDTO $entity */
$entity = $query;
/** @var LoyaltyMember $user */
$user = $this->security->getUser();
$sessionTicketTypes = $this->ticketRepository->findByCinemaIdSessionId(
$di_map['host_cinema_id'],
$session->getSessionId(),
$user ? $user->getUserSessionId() : null
);
// Add Car Tickets with bonus card
if ($CBCCarCount = $entity->getNumberOfCBCCar()) {
foreach ($sessionTicketTypes as $type) {
if (strpos($type->getDescriptionAlt(), $di_map['cbc_car_ticket_description_contains']) !== false) {
break;
}
}
$ticket = (new Ticket())->setTicketDetails((new TicketDetails())->setTicketTypeCode($type->getTicketTypeCode()));
for ($i = 0; $i < $CBCCarCount; $i++) {
$entity->addTicket($ticket);
}
}
// Regular Car Ticket
if ($CarCount = $entity->getNumberOfCar()) {
foreach ($sessionTicketTypes as $type) {
if (strpos($type->getDescriptionAlt(), $di_map['car_ticket_description_contains']) !== false) {
break;
}
}
$ticket = (new Ticket())->setTicketDetails((new TicketDetails())->setTicketTypeCode($type->getTicketTypeCode()));
for ($i = 0; $i < $CarCount; $i++) {
$entity->addTicket($ticket);
}
}
// Car-Additional Ticket
if ($CarAdditionalCount = $entity->getNumberOfAdditionalCar()) {
foreach ($sessionTicketTypes as $type) {
if (strpos($type->getDescriptionAlt(), $di_map['car_additional_ticket_description_contains']) !== false) {
break;
}
}
$ticket = (new Ticket())->setTicketDetails((new TicketDetails())->setTicketTypeCode($type->getTicketTypeCode()));
for ($i = 0; $i < $CarAdditionalCount; $i++) {
$entity->addTicket($ticket);
}
}
// Car-Additional Ticket with bonus card
if ($CBCCarAdditionalCount = $entity->getNumberOfCBCAdditionalCar()) {
foreach ($sessionTicketTypes as $type) {
if (strpos($type->getDescriptionAlt(), $di_map['cbc_car_additional_ticket_description_contains']) !== false) {
break;
}
}
$ticket = (new Ticket())->setTicketDetails((new TicketDetails())->setTicketTypeCode($type->getTicketTypeCode()));
for ($i = 0; $i < $CBCCarAdditionalCount; $i++) {
$entity->addTicket($ticket);
}
}
// Car-Berth (Kojen) Ticket
if ($CarBerthCount = $entity->getNumberOfBerthCar()) {
foreach ($sessionTicketTypes as $type) {
if (strpos($type->getDescriptionAlt(), $di_map['car_berth_ticket_description_contains']) !== false) {
break;
}
}
$ticket = (new Ticket())->setTicketDetails((new TicketDetails())->setTicketTypeCode($type->getTicketTypeCode()));
for ($i = 0; $i < $CarBerthCount; $i++) {
$entity->addTicket($ticket);
}
}
// Car-Berth (Kojen) Ticket with bonus card
if ($CBCCarBerthCount = $entity->getNumberOfCBCBerthCar()) {
foreach ($sessionTicketTypes as $type) {
if (strpos($type->getDescriptionAlt(), $di_map['cbc_car_berth_ticket_description_contains']) !== false) {
break;
}
}
$ticket = (new Ticket())->setTicketDetails((new TicketDetails())->setTicketTypeCode($type->getTicketTypeCode()));
for ($i = 0; $i < $CBCCarBerthCount; $i++) {
$entity->addTicket($ticket);
}
}
$order = $this->orderRepository->setTickets($order, (new SetTicketsForSessionRequest())->setTickets($entity->getTickets()), $session->getSessionId());
$this->orderRepository->save($order);
return $setTicketsOnServerResponse;
} else {
$this->logger->debug('standard (not drive in) session selected');
do {
$seatPlanResponse = null;
try{
$start = microtime(true);
$seatPlanResponse = $this->getSeatPlan($order->getCinemaId(), $session->getSessionId(), null, false);
$this->logger->info(sprintf("profiling seat selection :: getSeatPlan execution time: %f", microtime(true) - $start));
} catch (SeatPlanException $spe){
throw new SeatPlanException($this->translator->trans($spe->getMessage()));
}
$setTicketsOnServerResponse = (new SetTicketsOnServerResponse())
->setSeatPlan($seatPlanResponse)
->setOrder($order);
$seatPlanRows = $seatPlanResponse->getRows();
if ($colunIndex = call_user_func(function ($rows) {
foreach ($rows as $row) {
if ($seats = $row->getSeats()) {
return $seats[0]->getPosition()->getColumnIndex();
}
}
}, $seatPlanRows)) {
$this->logger->debug("columnIndex $colunIndex");
}
foreach ($seatPlanRows as &$seatPlanRow) {
foreach ($seatPlanRow->getSeats() as &$seat) {
$seat->getPosition()->setColumnIndex($seat->getPosition()->getColumnIndexVista());
}
}
$start = microtime(true);
[$positions, $selection, $selectedSeatData] = $this->getSeats($seatPlanRows, $query, $order);
$this->logger->info(sprintf("profiling seat selection :: this->getSeats execution time: %f", microtime(true) - $start));
// without selection
foreach ($positions as $position) {
$position->setColumnIndex($position->getColumnIndexVista());
}
try {
$this->checkGettingSeats($selection, $selectedSeatData);
/** @var TicketDTO $entity */
$entity = $query;
/** @var LoyaltyMember $user */
$user = $this->security->getUser();
$sessionTicketTypes = $this->ticketRepository->findByCinemaIdSessionId(
$session->getCinemaId(),
$session->getSessionId(),
$user ? $user->getUserSessionId() : null
);
$tickettypes = '';
foreach ($sessionTicketTypes as $tickettype) {
$tickettypes .= sprintf('-> %s (Alt: %s) ', $tickettype->getDescription(), $tickettype->getDescriptionAlt());
}
$this->logger->debug(sprintf('available tickets [%s] [%s]: %s', $session->getCinemaId(), $session->getSessionId(), $tickettypes));
[$normalized] = $this->getNormalized($seatPlanRows);
$seats = $this->getSeatsFromSeatPlan($normalized, $positions);
$wheelChairs = from($seats)->where(function (array $item) {
/** @var Seat $seat */
[, $seat] = $item;
return strpos($seat->getId(), 'R') !== false;
})->toArray();
$wheelChairsCount = count($wheelChairs ?: []);
if ($wheelChairsCount > 0 && in_array(getenv('APP_COUNTRY'), ['hrv', 'mne', 'srb'])) {
$this->logger->debug('Disable wheelchair ticket booking');
throw new SeatPlanException(
$this->translator->trans(
'seat.no_wheelchair_tickets'
)
);
}
$filmBrunchAdultsCount = $entity->getNumberOfFilmBrunchSeats();
$filmBrunchChildrenCount = $entity->getNumberOfFilmBrunchChildSeats();
$packageWheelchairCount = 0;
$adultsCount = $entity->getNumberOfSeats();
$childrenCount = $entity->getNumberOfChildSeats();
$reducedCount = $entity->getNumberOfReducedSeats();
$packageReducedCount = $entity->getNumberOfPackageReducedSeats();
$packageRegularCount = $entity->getNumberOfPackageRegularSeats();
$packageClubCount = $entity->getNumberOfPackageClubSeats();
$packageChildCount = $entity->getNumberOfPackageChildSeats();
$packageWheelchairCount = $entity->getNumberOfPackageWheelchairSeats();
// required to be backwards compatibe. old app does not send packages count
if ($packageReducedCount === null) $packageReducedCount = 0;
if ($packageRegularCount === null) $packageRegularCount = 0;
if ($packageClubCount === null) $packageClubCount = 0;
if ($packageChildCount === null) $packageChildCount = 0;
if ($packageWheelchairCount === null) $packageWheelchairCount = 0;
if (($wheelChairsCount - ($filmBrunchAdultsCount + $filmBrunchChildrenCount)) > 0) {
$adultsCount -= ($wheelChairsCount - ($filmBrunchAdultsCount + $filmBrunchChildrenCount));
}
($adultsCount < 0) and $adultsCount = 0;
$this->logger->debug(sprintf(
'--> wheelchairs: %d --> film brunch adult: %d --> film brunch child: %d --> adult: %d --> children: %d --> reduced: %d --> packageRegular: %d --> packageClub: %d --> packageChild: %d --> packageWheelchair: %d --> packageReducedCount: %d',
$wheelChairsCount,
$filmBrunchAdultsCount,
$filmBrunchChildrenCount,
$adultsCount,
$childrenCount,
$reducedCount,
$packageRegularCount,
$packageClubCount,
$packageChildCount,
$packageWheelchairCount,
$packageReducedCount
));
$wheelChairsOrderSeats = array_column($wheelChairs ?: [], 0);
$notWheelChairs = array_values(from($seats)->where(function (array $item) use ($wheelChairsOrderSeats) {
[$orderSeat] = $item;
return !array_filter($wheelChairsOrderSeats, function ($x) use ($orderSeat) {
return $orderSeat === $x;
});
})->toArray() ?: []);
$filmBrunchChildWheelChairsCount = 0;
$filmBrunchAdultWheelChairsCount = 0;
// convert child filmbrunchtickets to wheelchair child filmbrunch tickets
$standardWheelChairsCount = $wheelChairsCount - $filmBrunchChildrenCount;
if ($standardWheelChairsCount < 1) {
$standardWheelChairsCount = 0;
$filmBrunchChildWheelChairsCount = $wheelChairsCount;
$filmBrunchChildrenCount -= $wheelChairsCount;
$wheelChairsCount = 0;
} else {
$filmBrunchChildWheelChairsCount = $filmBrunchChildrenCount;
$filmBrunchChildrenCount = 0;
$wheelChairsCount -= $filmBrunchChildWheelChairsCount;
}
// convert the remaining wheelchair tickets to adult filmbrunch wheelchair tickets
$standardWheelChairsCount = $wheelChairsCount - $filmBrunchAdultsCount;
if ($standardWheelChairsCount < 1) {
$standardWheelChairsCount = 0;
$filmBrunchAdultWheelChairsCount = $wheelChairsCount;
$wheelChairsCount = 0;
} else {
$filmBrunchAdultWheelChairsCount = $filmBrunchAdultsCount;
$filmBrunchAdultsCount = 0;
$wheelChairsCount -= $filmBrunchAdultWheelChairsCount;
}
$standardWheelChairs = array_slice($wheelChairs, 0, $standardWheelChairsCount);
$filmBrunchAdultWheelChair = array_slice($wheelChairs, $standardWheelChairsCount, $filmBrunchAdultWheelChairsCount);
$filmBrunchChildWheelChair = array_slice($wheelChairs, $filmBrunchAdultWheelChairsCount + $standardWheelChairsCount);
$filmBrunchAdultsCount -= count($filmBrunchAdultWheelChair);
$filmBrunchChildrenCount -= count($filmBrunchChildWheelChair);
$this->logger->debug(sprintf(
'--> wheelchairs: %d --> film brunch adult: %d --> film brunch child: %d --> adult: %d --> children: %d --> reduced: %d --> packageRegular: %d --> packageClub: %d --> packageChild: %d --> packageWheelchair: %d --> packageReducedCount: %d ',
$standardWheelChairsCount,
$filmBrunchAdultsCount,
$filmBrunchChildrenCount,
$adultsCount,
$childrenCount,
$reducedCount,
$packageRegularCount,
$packageClubCount,
$packageChildCount,
$packageWheelchairCount,
$packageReducedCount
));
$adults = array_slice($notWheelChairs, 0, $adultsCount);
$children = array_slice($notWheelChairs, $adultsCount, $childrenCount);
$reduced = array_slice($notWheelChairs, $adultsCount + $childrenCount, $reducedCount);
$filmBrunchAdults = array_slice($notWheelChairs, $adultsCount + $childrenCount + $reducedCount, $filmBrunchAdultsCount);
$filmBrunchChildren = array_slice($notWheelChairs, $adultsCount + $childrenCount + $filmBrunchAdultsCount + $reducedCount, $filmBrunchChildrenCount);
$packageReducedSeats = array_slice($notWheelChairs, $adultsCount + $childrenCount, $packageReducedCount);
$packageRegularSeats = array_slice($notWheelChairs, $adultsCount + $childrenCount, $packageRegularCount);
$packageClubSeats = array_slice($notWheelChairs, $adultsCount + $childrenCount, $packageClubCount);
$packageChildSeats = array_slice($notWheelChairs, $adultsCount + $childrenCount, $packageChildCount);
$packageWheelchairSeats = array_slice($notWheelChairs, $adultsCount + $childrenCount, $packageWheelchairCount);
$this->logger->debug(sprintf(
'Array Count: wheelchair: %d not wheelchair: %d fbwheelchair a: %d fbwheelchair c: %d adult: %d child: %d reduced: %d fb a: %d fb c: %d packageReducedSeats: %d packageRegularSeats: %d packageClubSeats: %d packageChildSeats: %d packageWheelchairSeats: %d',
count($standardWheelChairs),
count($notWheelChairs),
count($filmBrunchAdultWheelChair),
count($filmBrunchChildWheelChair),
count($adults),
count($children),
count($reduced),
count($filmBrunchAdults),
count($filmBrunchChildren),
count($packageReducedSeats),
count($packageRegularSeats),
count($packageClubSeats),
count($packageChildSeats),
count($packageWheelchairSeats)
));
$sources = [
[
array_column($standardWheelChairs, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows, $entity) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, $entity->isBonusCard(), false, false, false);
}
],
[
array_column($filmBrunchAdultWheelChair, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows, $entity) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, $entity->isBonusCard(), false, false, true);
}
],
[
array_column($filmBrunchChildWheelChair, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows, $entity) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, $entity->isBonusCard(), true, false, true);
}
],
[
array_column($adults, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows, $entity) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, $entity->isBonusCard(), false, false, false);
}
],
[
array_column($children, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, false, true, false, false);
}
],
[
array_column($reduced, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, false, false, true, false);
}
],
[
array_column($filmBrunchAdults, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, false, false, false, true);
}
],
[
array_column($filmBrunchChildren, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, false, true, false, true);
}
],
[
array_column($packageReducedSeats, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, false, false, false, false, false, true);
}
],
[
array_column($packageRegularSeats, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, false, false, false, false, true);
}
],
[
array_column($packageClubSeats, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows, $entity) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, $entity->isBonusCard(), false, false, false, false, false, true);
}
],
[
array_column($packageChildSeats, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, false, false, false, false, false, false, false, true);
}
],
[
array_column($packageWheelchairSeats, 0),
function ($seat) use ($sessionTicketTypes, $seatPlanRows) {
return $this->findTicket($sessionTicketTypes, $seatPlanRows, $seat, false, false, false, false);
}
]
];
foreach ($seats as $item) {
list($targetOrderSeat) = $item;
foreach ($sources as $s) {
foreach ($s[0] as $orderSeat) {
if (
$targetOrderSeat->getRowIndex() == $orderSeat->getRowIndex() &&
$targetOrderSeat->getColumnIndex() == $orderSeat->getColumnIndex() &&
$targetOrderSeat->getAreaNumber() == $orderSeat->getAreaNumber()
) {
$targetOrderSeat->setColumnIndexVista($targetOrderSeat->getColumnIndex());
$targetOrderSeat->setColumnIndex($targetOrderSeat->getColumnIndexVista());
$entity->addTicket($s[1]($targetOrderSeat));
}
}
}
}
$start = microtime(true);
$order = $this->orderRepository->setTickets($order, (new SetTicketsForSessionRequest())->setTickets($entity->getTickets()), $session->getSessionId());
$this->logger->info(sprintf("profiling seat selection :: orderRepository->setTickets execution time: %f", microtime(true) - $start));
$order->setSelection($selection);
$start = microtime(true);
$this->orderRepository->save($order);
$this->logger->info(sprintf("profiling seat selection :: orderRepository->save execution time: %f", microtime(true) - $start));
break;
} catch (\Exception $ex) {
$this->logger->error(sprintf("Exception in SeatPlanManager.php (%d): %s ", __LINE__, $ex->getMessage()));
if ($this->shouldRetry($ex, $setTicketsOnServerResponse)) {
$this->logger->info('retrying');
continue;
}
}
} while ($seatPlanRows && !$setTicketsOnServerResponse->getErrorMessage());
}
if ($seatPlanRows && $initSelection) {
$this->cleanUpSelection($seatPlanRows, $initSelection);
}
$this->getNormalized($seatPlanRows, null, $order->getSelection());
$this->fillSeatPlanWithIcons($seatPlanRows, $order->getCinemaId());
foreach ($seatPlanRows as &$row) {
foreach ($row->getSeats() as &$seat) {
$seat->getPosition()->setColumnIndex($seat->getPosition()->getColumnIndexRender());
}
}
$icons = [];
$seatPlanRows = $this->applySaved($seatPlanRows, $icons, $order->getCinemaId(), $session->getSessionId(), true);
$setTicketsOnServerResponse->getSeatPlan()->setRows($seatPlanRows);
// remove next rows after first one
// $preparedRows = [];
// $previousPhysicalName = null;
// foreach($setTicketsOnServerResponse->getSeatPlan()->getRows() as $row) {
// if ($row->getPhysicalName() != null && $previousPhysicalName == $row->getPhysicalName()) {
// continue;
// }
// $previousPhysicalName = $row->getPhysicalName();
// $preparedRows[] = $row;
// }
// $setTicketsOnServerResponse->getSeatPlan()->setRows($preparedRows);
return $setTicketsOnServerResponse;
}
/**
* @param array $sessionTicketTypes
* @param array $seatPlanRows
* @param SeatPosition $seat
* @param bool $isBonus
* @param bool $isChild
*
* @return Ticket
* @throws SeatPlanException
*/
protected function findTicket(
array $sessionTicketTypes,
array $seatPlanRows,
SeatPosition $seat,
bool $isBonus,
bool $isChild = false,
bool $isReduced = false,
bool $isFilmBrunch = false,
bool $isPackageRegular = false,
bool $isPackageReduced = false,
bool $isPackageClub = false,
bool $isPackageChild = false
): Ticket {
//$this->logger->debug("entering findTicket() -- isBonus: [$isBonus] ");
$this->logger->debug("entering findTicket()");
[$areaCategoryCode, $isWheelchair] = $this->findAreaCategoryCodeBySeat($seatPlanRows, $seat);
foreach ($sessionTicketTypes as $item) {
/*
$packageConcessions = $item->getPackageContent()->getConcessions();
$packageTickets = $item->getPackageContent()->getTickets();*/
if (
1
&& intval($item->getAreaCategoryCode()) === intval($areaCategoryCode)
// && ($packageConcessions === null || count($packageConcessions) === 0)
// && ($packageTickets === null || count($packageTickets) === 0)
) {
if (
1
&& strpos($item->getDescriptionAlt(), 'Wheelchair') !== false
&& strpos($item->getDescriptionAlt(), 'Package Wheelchair') === false
&& strpos($item->getDescriptionAlt(), 'PCK') === false
&& !$item->isChildOnlyTicket()
&& $isWheelchair
&& !$isChild
&& !$isReduced
&& !$isFilmBrunch
) {
$this->logger->info('selecting standard wheelchair ticket');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Package Wheelchair') !== false
&& !$item->isChildOnlyTicket()
&& $isWheelchair
&& !$isChild
&& !$isReduced
&& !$isFilmBrunch
) {
$this->logger->info('selecting Package Wheelchair ticket');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Child') !== false
&& strpos($item->getDescriptionAlt(), 'Package Child') === false
&& strpos($item->getDescriptionAlt(), 'PCK') === false
&& $item->isChildOnlyTicket()
&& !$isWheelchair
&& $isChild
&& !$isReduced
&& !$isBonus
&& !$isFilmBrunch
) {
$this->logger->info('selecting child ticket');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Package Child') !== false
&& $item->isChildOnlyTicket()
&& !$isWheelchair
&& !$isChild
&& !$isReduced
&& !$isBonus
&& !$isFilmBrunch
&& $isPackageChild
) {
$this->logger->info('selecting Package Child');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& ( stripos($item->getDescriptionAlt(), 'Ermäßigt') !== false || stripos($item->getDescriptionAlt(), 'Student') !== false )
&& !$item->isChildOnlyTicket()
&& !$isWheelchair
&& !$isChild
&& $isReduced
&& !$isBonus
&& !$isFilmBrunch
) {
$this->logger->info('selecting reduced (Ermäßigt) ticket');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Filmbrunch Pkg RE') !== false
&& $isWheelchair
&& !$isChild
&& !$isReduced
&& $isFilmBrunch
) {
$this->logger->info('selecting filmbrunch adult wheelchair ticket');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Filmbrunch Pkg RK') !== false
&& $isWheelchair
&& $isChild
&& !$isReduced
&& $isFilmBrunch
) {
$this->logger->info('selecting filmbrunch child wheelchair ticket');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'CBC') !== false
&& !$item->isChildOnlyTicket()
&& !$isWheelchair
&& !$isChild
&& !$isReduced
&& $isBonus
&& !$isFilmBrunch
) {
$this->logger->info('selecting CBC ticket');
return $this->getTicketDetails($item, $seat, true);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Package Club') !== false
&& !$item->isChildOnlyTicket()
&& !$isWheelchair
&& !$isChild
&& !$isReduced
&& $isBonus
&& !$isFilmBrunch
&& $isPackageClub
) {
$this->logger->info('selecting Package Club');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Regular') !== false
&& strpos($item->getDescriptionAlt(), 'Package Regular') === false
&& strpos($item->getDescriptionAlt(), 'PCK') === false
&& !$item->isChildOnlyTicket()
&& !$isWheelchair
&& !$isChild
&& !$isReduced
&& !$isBonus
&& !$isFilmBrunch
&& !$isPackageRegular
) {
$this->logger->info('selecting adult ticket');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Package Regular') !== false
&& !$item->isChildOnlyTicket()
&& !$isWheelchair
&& !$isChild
&& !$isReduced
&& !$isBonus
&& !$isFilmBrunch
&& !$isPackageReduced
&& !$isPackageClub
&& $isPackageRegular
) {
$this->logger->info('selecting Package Regular');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Package Reduced') !== false
&& !$item->isChildOnlyTicket()
&& !$isWheelchair
&& !$isChild
&& !$isReduced
&& !$isFilmBrunch
&& $isPackageReduced
) {
$this->logger->info('selecting Package Reduced');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Filmbrunch Pkg E') !== false
&& !$item->isChildOnlyTicket()
&& !$isWheelchair
&& !$isChild
&& !$isReduced
&& $isFilmBrunch
) {
$this->logger->info('selecting filmbrunch adult ticket');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Filmbrunch Pkg K') !== false
&& !$item->isChildOnlyTicket()
&& !$isWheelchair
&& $isChild
&& !$isReduced
&& $isFilmBrunch
) {
$this->logger->info('selecting filmbrunch child ticket');
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Filmbrunch Pkg K') !== false
&& !$item->isChildOnlyTicket()
&& $isChild
&& !$isReduced
&& $isFilmBrunch
) {
return $this->getTicketDetails($item, $seat, false);
} elseif (
1
&& strpos($item->getDescriptionAlt(), 'Filmbrunch Pkg K') !== false
&& !$item->isChildOnlyTicket()
&& $isChild
&& !$isReduced
&& $isFilmBrunch
) {
error_log(sprintf("%s %s(%s) isChildOnlyTicket {$item->isChildOnlyTicket()} getTicketTypeCode {$item->getTicketTypeCode()} ", date('Y-m-d H:i:s'), __METHOD__, __LINE__)); // . var_export([$item, $seat], true)
return $this->getTicketDetails($item, $seat, false);
}
}/* else {
$this->logger->info(sprintf('%s is excluded', $item->getDescriptionAlt()));
}*/
}
if ($isChild) {
throw SeatPlanException::create(
'No child tickets available for the selection',
SeatPlanException::CODE_SEATPLAN_NO_CHILD_TICKET_IS_AVAILABLE
);
} else {
throw new SeatPlanException(
$this->translator->trans(
'seat.no_tickets',
[
'%area%' => $seat->getAreaNumber(),
'%row%' => $seat->getRowIndex(),
'%column%' => $seat->getColumnIndex(),
]
)
);
}
}
protected function findAreaCategoryCodeBySeat(array $rows, SeatPosition $orderSeat): array
{
$count = -1;
//error_log(sprintf("%s %s(%s) getAreaNumber {$orderSeat->getAreaNumber()} getRowIndex {$orderSeat->getRowIndex()} getColumnIndex {$orderSeat->getColumnIndex()}", date('Y-m-d H:i:s'), __METHOD__, __LINE__));
/** @var Row $row */
foreach ($rows ?: [] as $row) {
//error_log(sprintf("%s %s(%s) getPhysicalName {$row->getPhysicalName()} getAreaCategoryCode {$row->getAreaCategoryCode()} count %s ",
// date('Y-m-d H:i:s'), __METHOD__, __LINE__, ++$count));
/** @var Seat $seat */
foreach ($row->getSeats() ?: [] as $seat) {
$position = $seat->getPosition();
// if($row->getPhysicalName() == 13) {
// error_log(sprintf("%s %s(%s) getPhysicalName {$row->getPhysicalName()} getAreaNumber {$position->getAreaNumber()} getRowIndex {$position->getRowIndex()} getColumnIndex {$position->getColumnIndex()} count %s ", date('Y-m-d H:i:s'), __METHOD__, __LINE__, $count));
// }
if (
1
&& ($position->getAreaNumber() === $orderSeat->getAreaNumber())
&& ($position->getRowIndex() === $orderSeat->getRowIndex())
&& ($position->getColumnIndex() === $orderSeat->getColumnIndex())
) {
// error_log(sprintf("%s %s(%s) match!!! getPhysicalName {$row->getPhysicalName()} getAreaNumber {$position->getAreaNumber()} getRowIndex {$position->getRowIndex()} getColumnIndex {$position->getColumnIndex()} getAreaCategoryCode {$seat->getAreaCategoryCode()} count %s ", date('Y-m-d H:i:s'), __METHOD__, __LINE__, $count));
return [
$row->getAreaCategoryCode(),
strpos($seat->getId(), 'R') !== false
];
}
}
}
throw new \InvalidArgumentException(sprintf(
'Invalid seat position - Area number: %s, Row index: %s, Column index: %s',
$orderSeat->getAreaNumber(),
$orderSeat->getRowIndex(),
$orderSeat->getColumnIndex()
));
}
protected function getTicketDetails(SessionTicketType $ticket, SeatPosition $seat, bool $isBonus): Ticket
{
$ticketDetails = (new TicketDetails())->setTicketTypeCode($ticket->getTicketTypeCode());
/** @var LoyaltyMember $user */
if ($isBonus && ($user = $this->security->getUser())) {
$ticketDetails->setThirdPartyMemberScheme(
(new ThirdPartyMemberScheme())
->setMemberDateOfBirth($user->getDateOfBirth())
->setMemberCard($user->getCardNumber())
);
}
$orderSeat = new OrderSeat();
$orderSeat->setColumnIndex($seat->getColumnIndex())
->setAreaNumber($seat->getAreaNumber())
->setRowIndex($seat->getRowIndex());
return (new Ticket())->setTicketDetails($ticketDetails)->setSeats([$orderSeat]);
}
protected function checkGettingSeats($selection, $selectedSeatData)
{
$this->logger->info(" ---> entering checkGettingsSeats <---");
if (!$selectedSeatData) {
throw SeatPlanException::create(
'No seat is selected!',
SeatPlanException::CODE_SEATPLAN_NO_SEAT_IS_SELECTED
);
}
$this->logger->info(" ---> entering checkGettingsSeats <---");
if (!$selection) {
throw SeatPlanException::create(
$this->translator->trans('No selection is possible with such a criteria'),
SeatPlanException::CODE_SEATPLAN_NOTHING_COULD_BE_SELECTED
);
}
}
/**
* Check if error is recoverable
*
* @param \Exception $exception
* @param SetTicketsOnServerResponse $response
*
* @return bool
*/
private function shouldRetry(\Exception $exception, SetTicketsOnServerResponse $response): bool
{
$this->logger->debug('message: '.$exception->getMessage());
if (!$exception instanceof SeatPlanException) {
if (!$response->getErrorMessage()) {
$response->setErrorMessage($this->translator->trans($exception->getMessage()));
}
$this->logger->error('not a seatplan exception, omitting retry');
return false;
}
$response->setErrorMessage($exception->getMessage());
if (!$data = $exception->getData()) {
return false;
}
// if(!array_key_exists('errorCode', $data)) {
// error_log(sprintf("%s %s(%s) data ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . var_export([$data, debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)], true));
// }
if ($data['errorCode'] === '110') {
$response->setErrorMessage($this->translator->trans('Seat sold out'));
return true;
}
if ($data['errorCode'] === '140') {
$response->setErrorMessage($this->translator->trans('Limit of CBC Tickets for the day requested has been reached'));
return false;
}
return false;
}
/**
* @param Row[] $seatPlanRows
* @param Seat $selectedSeat
* @param int $selectedCount
* @param Seat[] $initSelection
*
* @return array
*/
public function select(array $seatPlanRows, ?Seat $selectedSeat, int $selectedCount = 0, array $initSelection = []): array
{
if (!$selectedSeat || !$selectedCount) {
return [];
}
return $this->doSelect($seatPlanRows, $selectedSeat, $selectedCount, $initSelection);
}
/**
* @param Row[] $seatPlan
* @param Seat $selectedSeat
* @param int $selectedCount
* @param Seat[] $initSelection
*
* @return array
*/
protected function doSelect(array $seatPlan, Seat $selectedSeat, int $selectedCount, array $initSelection = []): array
{
// error_log(sprintf("%s %s(%s) selectedSeat ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . var_export($selectedSeat, true));//,debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5)]
list($normalized, $selectedSeat) = $this->getNormalized(
$seatPlan,
$selectedSeat,
$initSelection
);
//error_log(sprintf("%s %s(%s) normalized,selectedSeat ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . var_export([array_slice($normalized[9],0,4), $selectedSeat], true));
$list = $this->getWalkThroughIndexes(array_keys($normalized), $selectedSeat->getNormalizedRowIndex());
foreach ($list as $index) {
if ($selection = $this->processRow($normalized[$index], $selectedSeat, $selectedCount)) {
return $selection;
}
}
$this->logger->debug('returning empty array');
return [];
}
protected function processRow($row, Seat $selectedSeat, $selectedCount)
{
$this->rowGroups__ = $rowGroups = $this->extractRanges(
$row,
$selectedSeat,
function ($index, $seat) {
/** @var Seat $seat */
return intval($seat->getColumnIndex());
},
1,
false
);
$ranges = $this->extractRanges(
$row,
$selectedSeat,
function ($index, $seat) {
/** @var Seat $seat */
return intval($index);
},
$selectedCount
);
$availableSelections = [];
if ($this->restrictions->getAllowBookingSplitting()) {
// use unfiltered rowGroups
$this->logger->debug('splitted booking is allowed');
foreach ($rowGroups as $item) {
$selection = $this->processRange($row, $item, $selectedSeat, $selectedCount);
$selection and $availableSelections[] = $selection;
}
} else {
// use filtered ranges to avoid splitted ticket bookings
$this->logger->debug('splitted booking is NOT allowed');
foreach ($ranges as $item) {
$selection = $this->processRange($row, $item, $selectedSeat, $selectedCount);
$selection and $availableSelections[] = $selection;
}
}
// error_log(sprintf("%s %s(%s) availableSelections ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . var_export(count($availableSelections), true));
usort($availableSelections, function ($a, $b) use ($selectedSeat) {
$aDistance = abs($a[0]->getNormalizedColumnIndex() - $selectedSeat->getNormalizedColumnIndex());
$bDistance = abs($b[0]->getNormalizedColumnIndex() - $selectedSeat->getNormalizedColumnIndex());
if ($aDistance < $bDistance) {
return -1;
} elseif ($aDistance > $bDistance) {
return 1;
}
return 0;
});
// error_log(sprintf("%s %s(%s) availableSelections ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . var_export(count($availableSelections), true));
if ($availableSelections) {
return array_shift($availableSelections);
}
return [];
}
/**
* @param Seat[] $row
* @param Seat[] $range
* @param Seat $selectedSeat
* @param int $selectedCount
*
* @return array
*/
protected function processRange(array $row, array $range, Seat $selectedSeat, int $selectedCount): array
{
$availableSelections = [];
$positions = count($range) - $selectedCount + 1;
for ($shift = 0; $shift < $positions; $shift++) {
$selection = array_slice($range, $shift, $selectedCount);
$rowGroups = [];
foreach (array_keys($this->rowGroups__) as $index) {
$rowGroups[$index] = array_filter(
$this->rowGroups__[$index],
function (Seat $item) use ($selection) {
return !array_filter(
$selection,
function (Seat $element) use ($selection, $item) {
return $element === $item;
}
);
}
);
}
$this->rowGroupsSingletons__ = $rowGroupsSingletons = array_values(array_map(
function ($item) {
return array_shift($item);
},
array_filter(
$rowGroups,
function ($item) {
return count($item ?: []) == 1;
}
)
));
if ($this->okSelection($row, $selection)) {
// if a wheelchair is the selection result and originally NO WHEELCHAIR was selected, the result is not valid
if (false === ($selection[0]->getOriginalStatus() === 3 && $selectedSeat->getOriginalStatus() !== 3)) {
$availableSelections[] = $selection;
}
}
}
// error_log(sprintf("%s %s(%s) count(availableSelections) ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . var_export(count($availableSelections), true));
usort($availableSelections, function ($a, $b) use ($selectedSeat) {
$aDistance = abs($a[0]->getNormalizedColumnIndex() - $selectedSeat->getNormalizedColumnIndex());
$bDistance = abs($b[0]->getNormalizedColumnIndex() - $selectedSeat->getNormalizedColumnIndex());
if ($aDistance < $bDistance) {
return -1;
} elseif ($aDistance > $bDistance) {
return 1;
}
return 0;
});
if ($availableSelections) {
return array_shift($availableSelections);
}
return [];
}
/**
* @param Seat[] $row
* @param Seat[] $selection
*
* @return bool
*/
protected function okSelection(array $row, array $selection)
{
$resultItems = [
$this->hasErrorSelectionForSingleEdgeSeats($row, $selection),
$this->hasErrorSelectionForCoronaDistance($row, $selection),
$this->hasErrorSelectionForIncompleteDoubleSeats($row, $selection),
];
$this->logger->debug(sprintf(
'SingleEdgeSeatError: %s, CoronaDistanceError: %s, IncompleteDoubleSeatsError: %s',
var_export($resultItems[0], true),
var_export($resultItems[1], true),
var_export($resultItems[2], true)
));
$preResult = 1;
foreach ($resultItems as $item) {
$preResult *= intval(!$item);
}
return boolval($preResult);
}
/**
* @param Seat[] $row
* @param Seat[] $selection
*
* @return bool
*/
protected function hasErrorSelectionForIncompleteDoubleSeats(array $row, array $selection): bool
{
$groupsList = [];
foreach ($row as $item) {
if (!empty($item->getDoubleSeatId())) {
$groupsList[$item->getDoubleSeatId()][] = $item;
}
}
foreach ($groupsList as $groupId => $group) {
$freeCount = 0;
foreach ($group as $item) {
$isSeatFree = in_array($item->getStatusCalculated(), self::FREE_STATUSES);
$isSeatSelected = array_filter($selection, function ($element) use ($item) {
return $this->isSeatPositionEq($element, $item);
});
if ($isSeatFree && !$isSeatSelected) {
++$freeCount;
}
}
if (1 === $freeCount) {
return true;
}
}
return false;
}
/**
* @param Seat[] $row
* @param Seat[] $selection
*
* @return bool
*/
protected function hasErrorSelectionForSingleEdgeSeats(array $row, array $selection): bool
{
if ($this->restrictions->getApplyCoronaDistance()) {
// check only if corona distance does not apply
return false;
}
$expressionLanguage = new ExpressionLanguage();
$rowIndexed = [];
foreach ($row as $item) {
$rowIndexed[$item->getNormalizedColumnIndex()] = $item;
}
$selectionIndexes = [];
foreach ($selection as $item) {
$selectionIndexes[] = $item->getNormalizedColumnIndex();
}
$max = max($selectionIndexes);
$maxSeat0 = $rowIndexed[$max] ?? null;
$maxSeat1 = $rowIndexed[$max + 1] ?? null;
$maxSeat2 = $rowIndexed[$max + 2] ?? null;
$min = min($selectionIndexes);
$minSeat0 = $rowIndexed[$min] ?? null;
$minSeat1 = $rowIndexed[$min - 1] ?? null;
$minSeat2 = $rowIndexed[$min - 2] ?? null;
// zero is the selected seat, first and second are the next and nextnext (left or right)
$check = function (?Seat $zero, ?Seat $first, ?Seat $second, bool $syncDirections) use ($expressionLanguage) {
if (!$first) {
return false;
}
$eval = $expressionLanguage->evaluate(
sprintf('first %s zero', $syncDirections ? '>' : '<'),
[
'first' => $first->getColumnIndex(),
'zero' => $zero->getColumnIndex(),
]
);
$indexCheckFirst = ($second && abs($second->getColumnIndex() - $first->getColumnIndex()) > 1);
$indexCheckZero = ($eval && $first->getOriginalStatus() !== 3 && abs($first->getColumnIndex() - $zero->getColumnIndex()) == 1);
$statusCheck = ($second && !in_array($second->getStatusCalculated(), self::FREE_STATUSES));
$freeStatus = in_array($first->getStatusCalculated(), self::FREE_STATUSES);
$notSame = !array_filter($this->rowGroupsSingletons__, function ($item) use ($first) {
return $item == $first;
});
$result = $indexCheckZero
&&
$freeStatus
&&
$notSame
&& (!$second || $indexCheckFirst || $statusCheck);
return $result;
};
$row or $row = [];
$currentDirection = (function (array $row) {
if (count($row) < 2) {
return null;
}
/** @var Seat $zero */
$zero = $row[0];
/** @var Seat $first */
$first = $row[1];
return (0
|| $first->getColumnIndex() >= $zero->getColumnIndex()
|| (1
&& $first->getColumnIndex() < $zero->getColumnIndex()
&& intval($first->getAreaCategoryCode()) != intval($zero->getAreaCategoryCode()))) ? 'LEFT' : 'RIGHT';
})($row);
$resultLeft = $check($maxSeat0, $maxSeat1, $maxSeat2, $currentDirection == 'LEFT');
$resultRight = $check($minSeat0, $minSeat1, $minSeat2, $currentDirection == 'RIGHT');
$result = $resultLeft || $resultRight;
return $result;
}
/**
* @param Seat[] $row
* @param Seat[] $selection
*
* @return bool
*/
protected function hasErrorSelectionForCoronaDistance(array $row, array $selection): bool
{
if (!$this->restrictions->getApplyCoronaDistance()) {
// check only if we have to apply corona distance
return false;
}
$expressionLanguage = new ExpressionLanguage();
$rowIndexed = [];
foreach ($row as $item) {
$rowIndexed[$item->getNormalizedColumnIndex()] = $item;
}
$selectionIndexes = [];
foreach ($selection as $item) {
$selectionIndexes[] = $item->getNormalizedColumnIndex();
}
$max = max($selectionIndexes);
$maxSeat0 = $rowIndexed[$max] ?? null;
$maxSeat1 = $rowIndexed[$max + 1] ?? null;
$maxSeat2 = $rowIndexed[$max + 2] ?? null;
$min = min($selectionIndexes);
$minSeat0 = $rowIndexed[$min] ?? null;
$minSeat1 = $rowIndexed[$min - 1] ?? null;
$minSeat2 = $rowIndexed[$min - 2] ?? null;
$check = function (?Seat $zero, ?Seat $first, ?Seat $second, bool $syncDirections) use ($expressionLanguage) {
if (!$first) {
return false;
}
$eval = $expressionLanguage->evaluate(
sprintf('first %s zero', $syncDirections ? '>' : '<'),
[
'first' => $first->getColumnIndex(),
'zero' => $zero->getColumnIndex(),
]
);
$nextOneIsSeat = ($eval && abs($first->getColumnIndex() - $zero->getColumnIndex()) == 1);
return $nextOneIsSeat
&&
in_array($first->getStatusCalculated(), self::OCCUPIED_STATUSES)
&&
!array_filter($this->rowGroupsSingletons__, function ($item) use ($first) {
return $item == $first;
})
/*
&& (!$second
|| ($second && abs($second->getColumnIndex() - $first->getColumnIndex()) > 1)
|| ($second && !in_array($second->getStatusCalculated(), self::OCCUPIED_STATUSES))
)
*/;
};
$row or $row = [];
$currentDirection = (function (array $row) {
if (count($row) < 2) {
return null;
}
/** @var Seat $zero */
$zero = $row[0];
/** @var Seat $first */
$first = $row[1];
return (0
|| $first->getColumnIndex() >= $zero->getColumnIndex()
|| (1
&& $first->getColumnIndex() < $zero->getColumnIndex()
&& intval($first->getAreaCategoryCode()) != intval($zero->getAreaCategoryCode()))) ? 'LEFT' : 'RIGHT';
})($row);
return 0
|| $check($maxSeat0, $maxSeat1, $maxSeat2, $currentDirection == 'LEFT')
|| $check($minSeat0, $minSeat1, $minSeat2, $currentDirection == 'RIGHT');
}
/**
* @param Seat[] $row
* @param Seat $selectedSeat
* @param callable $getter
* @param int|null $minRangeLength
* @param bool|null $filterFirst
*
* @return array
*/
protected function extractRanges(array $row, Seat $selectedSeat, callable $getter, int $minRangeLength = 1, bool $filterFirst = true)
{
$filter = function (Seat $item) use ($selectedSeat) {
if (
in_array($item->getStatusCalculated(), self::FREE_STATUSES)
&& (strpos($item->getId(), 'R') !== false
|| strpos($selectedSeat->getId(), 'R') !== false
|| intval($item->getAreaCategoryCode()) == intval($selectedSeat->getAreaCategoryCode()))
) {
return true;
}
return false;
};
$filtered = $filterFirst
? array_filter($row, $filter)
: $row;
$result = $this->splitRow($filtered, $getter, $minRangeLength);
if (!$filterFirst) {
foreach (array_keys($result) as $index) {
$result[$index] = array_values(array_filter($result[$index], $filter));
}
}
return $result;
}
protected function splitRow($row, $getter, $minRangeLength)
{
$preResult = [];
$item = [];
/** @var Seat $prev */
$prev = null;
/**
* @var Seat $seat
*/
foreach ($row as $index => $seat) {
$diff = intval(abs($getter($index, $seat) - intval($prev)));
if (
!is_null($prev) && ($diff > 1 || $diff == 0)
) {
$preResult[] = $item;
$item = [];
}
$item[] = $seat;
$prev = $getter($index, $seat);
}
$preResult[] = $item;
return array_values(array_filter($preResult, function ($item) use ($minRangeLength) {
if (count($item) >= $minRangeLength) {
return true;
}
return false;
}));
}
protected function getWalkThroughIndexes($indexes, $touchIndex)
{
$indexes or $indexes = [];
if (is_null($touchIndex)) {
return [];
}
$key = array_search($touchIndex, $indexes);
if ($key === false) {
return [];
}
$listA = array_reverse(array_slice($indexes, 0, $key));
$listB = [];
(count($indexes) > $key + 1) and $listB = array_slice($indexes, $key + 1);
return array_merge([$key], $this->mixLists($listA, $listB));
}
protected function mixLists($listA, $listB)
{
$count = max(count($listA), count($listB));
$result = [];
for ($index = 0; $index < $count; $index++) {
foreach ([$listA, $listB] as $item) {
isset($item[$index]) and $result[] = $item[$index];
}
}
return $result;
}
/**
* Returns normalized seat plan representation [<Row> => [<Seat>, ...]]
*
* @param Row[] $seatPlanRows
* @param Seat|null $selectedSeat
* @param Seat[] $selection
*
* @return array<Seat|int|array<Seat>>
*/
public function getNormalized(array $seatPlanRows, ?Seat $selectedSeat = null, array $selection = []): array
{
$rows = [];
foreach ($seatPlanRows as $row) {
$rows[$row->getPhysicalName()] = array_merge($rows[$row->getPhysicalName()] ?? [], $row->getSeats());
}
$max = !$rows ? 1 : from($rows)
->max(function ($item) {
return count($item ?: []);
});
$seats = [];
foreach ($rows as $index => $item) {
$unitLength = 100 / $max;
usort($item, function (Seat $a, Seat $b) use ($unitLength) {
$aDist = ($a->getColumnIndex() * $unitLength) + floatval($a->getRowRight());
$bDist = ($b->getColumnIndex() * $unitLength) + floatval($b->getRowRight());
if ($aDist < $bDist) {
return -1;
} elseif ($aDist > $bDist) {
return 1;
}
return 0;
});
$seats[$index] = $item;
}
//if($seats && array_values($seats)[0])error_log(sprintf("%s %s(%s) ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . var_export(array_values($seats)[0][0], true));
$preResult = [];
foreach ($seats as $index => $rowSeats) {
$item = [];
/** @var Seat $seat */
foreach ($rowSeats as $seat) {
$item[] = $seat;
$seat->setRowName($index);
if ($this->isSeatPositionEq($selectedSeat, $seat)) {
$selectedSeat = $seat;
}
foreach ($selection as $selectionItem) {
if ($this->isSeatPositionEq($selectionItem, $seat)) {
$seat->setStatus(99);
}
}
}
$preResult[$index] = array_values($item);
}
$result = array_values($preResult);
// error_log(sprintf("%s %s(%s) ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . var_export(
// function($result){
// $seats = [];
// foreach ($result as $rowIndex => $row) {
// if($row[0]->getPosition()->getRowIndex() == 8 || $rowIndex == 8) {
// foreach ($row as $columnIndex => $seat) {
// if($seat->getStatus() == 99) {
// $seats[] = $seat;
// }
// }
// }
// }
// return $seats;
// }, true));
foreach ($result as $rowIndex => $row) {
/**
* @var Seat $item
*/
foreach ($row as $columnIndex => $item) {
$item->setNormalizedRowIndex($rowIndex);
$item->setNormalizedColumnIndex($columnIndex); //);$item->getPosition()->getColumnIndexVista()
}
}
//if($result && $result[0])error_log(sprintf("%s %s(%s) ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . var_export($result[0][0], true));
return [$result, $selectedSeat, $selection, $max];
}
public function isSeatPositionEq(?Seat $a, ?Seat $b): bool
{
if (!$a || !$b) {
return false;
}
if (
$a->getPosition()->getColumnIndex() === $b->getPosition()->getColumnIndex()
&& $a->getPosition()->getRowIndex() === $b->getPosition()->getRowIndex()
&& $a->getPosition()->getAreaNumber() === $b->getPosition()->getAreaNumber()
) {
return true;
}
return false;
}
/**
* @param array<int, array<Seat>> $normalized
* @param OrderSeat[] $orderSeats
*
* @return array
*/
public function getSeatsFromSeatPlan(array $normalized, array $orderSeats): array
{
$result = [];
foreach ($orderSeats as $orderSeat) {
$seat = (new Seat())->setPosition(
(new SeatPosition())
->setAreaNumber($orderSeat->getAreaNumber())
->setRowIndex($orderSeat->getRowIndex())
->setColumnIndex($orderSeat->getColumnIndex())
);
foreach ($normalized as $row) {
foreach ($row as $item) {
if ($this->isSeatPositionEq($item, $seat)) {
$result[] = [$orderSeat, $item];
continue 2;
}
}
}
}
return $result;
}
/**
* @param Row[] $rows
* @param Seat[] $selection
*
* @return void
*/
public function cleanUpSelection(array $rows, array $selection)
{
/** @var Row[] $filteredRows */
$filteredRows = [];
foreach ($rows as $item) {
if ($item->getPhysicalName() === (string) $selection[0]->getRowName()) {
$filteredRows[] = $item;
}
}
foreach ($filteredRows as $row) {
foreach ($row->getSeats() as $seat) {
foreach ($selection as $selectionItem) {
if ($this->isSeatPositionEq($seat, $selectionItem)) {
$seat->setStatus((strpos($seat->getId(), 'R') === false) ? 0 : 3);
continue;
}
}
}
}
}
/**
* @param string $seatPlanInput
* @param string $cinemaId
* @param string $screenNumber
* @param $seatPlanExists
* @param string $sessionId
*
* @return string
*/
public function processRaw(string $seatPlanInput, string $cinemaId, string $screenNumber, $seatPlanExists, string $sessionId)
{
//$seatPlanTree = $this->serializer->deserialize($seatPlanInput, SeatPlan::class, 'json');
$seatPlanTree = json_decode($seatPlanInput);
$this->setSeatPlanIcons($seatPlanTree, $cinemaId);
$this->reorderAreas($seatPlanTree);
//$seatPlanTree->setScreenNumber($screenNumber);
//$seatPlanTree->setSeatPlanExists($seatPlanExists);
//$seatPlanTree->setCinemaId($cinemaId);
//$seatPlanOutput = $this->serializer->serialize($seatPlanTree, 'json');
//$seatPlanOutput = preg_replace('/(.+)(\\}\s*)$/', "$1,\"screenNumber\":\"$screenNumber\",\"seatPlanExists\":\"$seatPlanExists\",\"cinemaId\":\"$cinemaId\"$2", $seatPlanInput);
$seatPlanTree->SeatLayoutData->screenNumber = $screenNumber;
$seatPlanTree->SeatLayoutData->seatPlanExists = $seatPlanExists;
$seatPlanTree->SeatLayoutData->cinemaId = $cinemaId;
$seatPlanTree->SeatLayoutData->sessionId = $sessionId;
foreach ($seatPlanTree->SeatLayoutData->Areas as &$area) {
$this->setVistaColumns($area->Rows);
}
//error_log(sprintf("%s %s(%s) ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . ' seatPlanTree ' . var_export($seatPlanTree, true));
$seatPlanOutput = json_encode($seatPlanTree);
return $seatPlanOutput;
}
public function reorderAreas(&$seatPlanTree)
{
usort($seatPlanTree->SeatLayoutData->Areas, function ($a, $b) {
$aMax = $this->getMaxRowName($a->Rows);
$bMax = $this->getMaxRowName($b->Rows);
return $aMax > $bMax ? 1 : ($aMax < $bMax ? -1 : 0);
});
$top = floatval(0);
foreach ($seatPlanTree->SeatLayoutData->Areas as &$area) {
$area->Top = $top;
$top += floatval($area->Height);
}
}
public function getMaxRowName($rows)
{
$rowMax = ' ';
foreach ($rows as $row) {
if ($rowMax < $row->PhysicalName) {
$rowMax = $row->PhysicalName;
}
}
return $rowMax;
}
public function reservationsToSaved2(&$rows, &$rowsSaved, $rowsMax)
{
//error_log(sprintf("%s %s(%s) ", date('Y-m-d H:i:s'), __METHOD__, __LINE__) . ' count($rows) ' . count($rows) . ' count($rowsSaved) ' . count($rowsSaved));
//return $rows; // !!!!!!!!!!!!!!!!!!!!!!!!!!!
error_log(sprintf("%s %s(%s) rows %d/%d added ", date('Y-m-d H:i:s'), __METHOD__, __LINE__, count($rows), count($rowsSaved)));
// join rows with the same physical name
$previousRow = null;
$preparedRows = [];
foreach ($rows as &$row) {
if ($previousRow == null) {
$previousRow = $row;
} else if ($previousRow->getPhysicalName() != $row->getPhysicalName()) {
$preparedRows[] = $previousRow;
$previousRow = $row;
} else {
// get right from saved rows
// move seats from next row to previous
//error_log(sprintf("%s %s(%s) before previousRow %d row %d", date('Y-m-d H:i:s'), __METHOD__, __LINE__, count($previousRow->getSeats()), count($row->getSeats())));
//$rowPair = $previousRow->getRight() < $row->getRight() ? [$previousRow, $row]: [$row, $previousRow];
if ($previousRow->getRight() < $row->getRight()) {
$rowPair = [$previousRow, $row];
} else {
$rowPair = [$row, $previousRow];
$previousRowTemp = $previousRow;
$previousRow = $row;
$row = $previousRowTemp;
}
$seats = [];
foreach ($rowPair as $rowPairEl) {
foreach ($rowPairEl->getSeats() as $s) {
$seats[] = $s;
}
}
$seeatCountBefore = count($previousRow->getSeats());
$previousRow->setSeats($seats);
error_log(sprintf("%s %s(%s) seeatCountBefore {$seeatCountBefore} and after previousRow %d", date('Y-m-d H:i:s'), __METHOD__, __LINE__, count($previousRow->getSeats())));
}
}
if ($previousRow) {
$preparedRows[] = $previousRow;
}
$rows = $preparedRows;
error_log(sprintf("%s %s(%s) row count after join %d", date('Y-m-d H:i:s'), __METHOD__, __LINE__, count($rows)));
//if($columnIndex=call_user_func(function($rows){$rowFirst=null;foreach($rows as $row){if($seats=$row->getSeats()){return $seats[0]->getPosition()->getColumnIndex();}}},$rows) || true){error_log(sprintf("%s %s(%s) columnIndex $columnIndex", date('Y-m-d H:i:s'), __METHOD__, __LINE__));}
foreach ($rows as &$row) {
if ($row->getPhysicalName() == 13) error_log(sprintf("%s %s(%s) getPhysicalName {$row->getPhysicalName()}", date('Y-m-d H:i:s'), __METHOD__, __LINE__));
if ($seats = $row->getSeats()) {
foreach ($row->getSeats() as &$seat) {
foreach ($rowsSaved as $rowSaved) {
if ($rowSaved->getSeats()) {
foreach ($rowSaved->getSeats() as $seatSaved) {
if (
$seat->getPosition()->getRowIndex() == $seatSaved->getPosition()->getRowIndex() &&
$seat->getPosition()->getAreaNumber() == $seatSaved->getPosition()->getAreaNumber() &&
$seat->getPosition()->getColumnIndex() == $seatSaved->getPosition()->getColumnIndexVista()
) {
if (($ri = $seatSaved->getPosition()->getColumnIndexVista()) != ($ci = $seatSaved->getPosition()->getColumnIndexRender()) && $seat->getStatus() == 99)
error_log(sprintf("%s %s(%s) row {$seat->getPosition()->getRowIndex()} vista $ri render $ci", date('Y-m-d H:i:s'), __METHOD__, __LINE__)); // . " vista {$seatSaved->getPosition()->getColumnIndexVista()} render {$seatSaved->getPosition()->getColumnIndexRender()}"
//$seat->setColumnIndex($seatSaved->getPosition()->getColumnIndexRender());
$seat->getPosition()->setColumnIndex($seatSaved->getPosition()->getColumnIndexRender());
$seat->getPosition()->setColumnIndexVista($seatSaved->getPosition()->getColumnIndexVista());
$seat->getPosition()->setColumnIndexRender($seatSaved->getPosition()->getColumnIndexRender());
$seat->setSeatsInGroup($seatSaved->getSeatsInGroup());
// if(($ri = $seatSaved->getPosition()->getRowIndex()) == 11 && ($ci = $seat->getPosition()->getColumnIndex()) > 10)error_log(sprintf("%s %s(%s) row $ri column $ci", date('Y-m-d H:i:s'), __METHOD__, __LINE__) .
// " vista {$seat->getPosition()->getColumnIndexVista()} render {$seat->getPosition()->getColumnIndexRender()}");
break;
}
}
}
}
}
}
}
//return $rows; // !!!!!!!!!!!!!!!!!!!!!!!!!!!
// join rows with equal physical names
// $rowsJoind = [];
// foreach($rows as &$row) {
// if($physicalName = $row->getPhysicalName()) {
// $rowAdded = null;
// sear for row with this physical name
// foreach($rowsJoind as &$rowJoind) {
// if($rowJoind->getPhysicalName() == $physicalName) {
// $rowAdded = $rowJoind;
// break;
// }
// }
// if($rowAdded) {
// if physical name already exists - join this row to it
// $rowJoind->setSeats($rowJoind->getSeats() + $row->getSeats());
// $rowJoind->setRight(min($rowJoind->getRight(), $row->getRight()));
// } else {
// if first row with this physical name - add it
// $rowsJoind[] = $row;
// }
// } else {
// if empty row - add it
// $rowsJoind[] = $row;
// }
// }
// if extra empty rows in the saved data - add them
$rowsJoind = $rows;
$preparedRows = [];
$rowsIndex = 0;
$rowsSavedIndex = 0;
$currentRowPosition = 0;
$currentRowSavedPosition = 0;
while ($currentRowPosition < count($rowsJoind) || $currentRowSavedPosition < count($rowsSaved)) {
// if current saved row is empty - add empty row and go to next
if ($currentRowSavedPosition < count($rowsSaved) && count($rowsSaved[$currentRowSavedPosition]->getSeats()) == 0) {
$preparedRows[] = new Row();
$currentRowSavedPosition++;
continue;
}
// if current vista row is empty - go to next row
if ($currentRowPosition < count($rowsJoind) && count($rowsJoind[$currentRowPosition]->getSeats()) == 0) {
$currentRowPosition++;
continue;
}
// if both rows exists - add vista row
if ($currentRowPosition < count($rowsJoind) && $currentRowSavedPosition < count($rowsSaved)) {
$preparedRows[] = $rowsJoind[$currentRowPosition];
if ($rowsJoind[$currentRowPosition]->getPhysicalName() != $rowsSaved[$currentRowSavedPosition]->getPhysicalName()) {
error_log(sprintf("%s %s(%s) different physical names rowsJoind[$currentRowPosition] %s rowsSaved[$currentRowSavedPosition] %s ", date('Y-m-d H:i:s'), __METHOD__, __LINE__, $rowsJoind[$currentRowPosition]->getPhysicalName(), $rowsSaved[$currentRowSavedPosition]->getPhysicalName()));
}
$currentRowSavedPosition++;
$currentRowPosition++;
}
}
error_log(sprintf("%s %s(%s) row count final %d", date('Y-m-d H:i:s'), __METHOD__, __LINE__, count($preparedRows)));
return $preparedRows;
}
}