403Webshell
Server IP : 202.61.199.114  /  Your IP : 216.73.217.139
Web Server : nginx/1.22.1
System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
User : web20 ( 1018)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/clients/client2/web18/web/src/PaCIM/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/clients/client2/web18/web/src/PaCIM/getEvents.php
<?php
require_once("includes/config.inc.php");
//echo API_CONNECTION;
//die();
/**
 * @var \Fusio\Engine\ConnectorInterface $connector
 * @var \Fusio\Engine\ContextInterface $context
 * @var \Fusio\Engine\RequestInterface $request
 * @var \Fusio\Engine\Response\FactoryInterface $response
 * @var \Fusio\Engine\ProcessorInterface $processor
 * @var \Psr\Log\LoggerInterface $logger
 * @var \Psr\SimpleCache\CacheInterface $cache
 */

use PSX\Http\Exception as StatusCode;

/** @var \Doctrine\DBAL\Connection $connection */
$connection = $connector->getConnection( API_CONNECTION );

// ---- Parameter sauber aufbereiten -------------------------------------------
// strtotime + festes Format normalisiert die Eingabe auf YYYY-MM-DD => injection-sicher
$dateParam = $request->getParameter('date');
$limit     = (int) $request->getParameter('limit');

$startDate     = $dateParam ? date('Y-m-d', strtotime($dateParam)) : null;
$year          = $startDate ? (int) date('Y', strtotime($startDate)) : (int) date('Y');
$nextYearStart = ($year + 1) . '-01-01';

$lower = $startDate ? '"' . $startDate . '"' : 'CURDATE()';

// sargbare Range-Bedingung (kein DATE_FORMAT auf der Spalte -> Index nutzbar)
$cond_b  = 'b.booking_begin >= '  . $lower . ' AND b.booking_begin < "'  . $nextYearStart . '"';
$cond_bs = 'bs.booking_begin >= ' . $lower . ' AND bs.booking_begin < "' . $nextYearStart . '"';


// ---- Result-Cache -----------------------------------------------------------
// Das Dashboard wird häufig gelesen, ändert sich aber nur im Sekundentakt (Check-ins).
// Die komplette Antwort wird kurz gecacht -> auf einen Cache-Hit folgen 0 DB-Queries.
// TTL nach Geschmack anpassen; auf 0 setzen deaktiviert das Caching komplett.
$cacheTtl = 10; // Sekunden
$cacheKey = 'pacim_getevents_' . md5(($startDate ?: 'today') . '|' . $limit);

if ($cacheTtl > 0) {
    $cached = $cache->get($cacheKey);
    if ($cached !== null) {
        return $response->build(200, [], $cached);
    }
}


// ---- COUNT ------------------------------------------------------------------
// Gegenüber dem Original:
//  * der LEFT JOIN auf pacim_invoice (ON i.invoice_id = b.booking_id) ist entfernt:
//    LEFT JOIN auf einen eindeutigen PK -> beeinflusst COUNT(*) nachweislich nicht.
//  * pacim_events_info entfernt: ebenfalls LEFT JOIN auf eindeutigen Key -> ohne Einfluss.
//  * der Event-Join ist sargbar (Range statt DATE_FORMAT auf der Spalte) -> Index nutzbar.
// Der zurückgegebene Wert bleibt damit identisch (Buchung × Event-Treffer).
$count = $connection->fetchColumn('
    SELECT COUNT(*)
    FROM pacim_booking b
        LEFT JOIN pacim_events e
            ON e.event_calendar_begin >= b.booking_begin
            AND e.event_calendar_begin < b.booking_begin + INTERVAL 1 DAY
            AND (e.event_calendar_title = b.booking_event
                 OR (e.event_calendar_end >= b.booking_end
                     AND e.event_calendar_end < b.booking_end + INTERVAL 1 DAY))
    WHERE ' . $cond_b . '
');


// ---- STATS EINMALIG pro (begin,end) -----------------------------------------
// Vorher wurde diese Aggregation zweimal über pacim_booking gefahren: einmal in der
// Tages-Query (GROUP BY begin) und einmal in der st-Derived-Table der Schiffe-Query
// (GROUP BY begin,end). Da SUM additiv ist, reicht EIN Scan auf (begin,end)-Ebene;
// die Tageswerte werden unten in PHP aufsummiert (mathematisch identisch).
$stats_be = $connection->fetchAll('
    SELECT
        b.booking_begin AS s_begin,
        b.booking_end   AS s_end,
        SUM(IF(b.booking_type = 1 AND i.invoice_status != 3, 1, 0)) AS halle,
        SUM(IF(b.booking_type = 1 AND i.invoice_status != 3 AND b.booking_checkin IS NOT NULL, 1, 0)) AS halle_checkin,
        SUM(IF(b.booking_type = 2 AND i.invoice_status != 3, 1, 0)) AS aussen,
        SUM(IF(b.booking_type = 2 AND i.invoice_status != 3 AND b.booking_checkin IS NOT NULL, 1, 0)) AS aussen_checkin,
        SUM(IF(i.invoice_status != 3 AND vp.has_valet = 1, 1, 0)) AS valet,
        SUM(IF(i.invoice_status != 3 AND vp.has_valet = 1 AND b.booking_checkin IS NOT NULL, 1, 0)) AS valet_checkin,
        SUM(IF(i.invoice_status != 3, 1, 0)) AS fahrzeuge,
        SUM(IF(i.invoice_status != 3 AND b.booking_checkin IS NULL, 1, 0)) AS wait_checkin,
        SUM(IF(i.invoice_status = 3, 1, 0)) AS storno
    FROM pacim_booking b
        LEFT JOIN pacim_invoice i ON i.invoice_id = b.booking_invoice
        LEFT JOIN (
            SELECT invoice_id, 1 AS has_valet
            FROM pacim_invoice_pos
            WHERE product_id = 8
            GROUP BY invoice_id
        ) vp ON vp.invoice_id = b.booking_invoice
    WHERE ' . $cond_b . '
    GROUP BY b.booking_begin, b.booking_end
    ORDER BY b.booking_begin ASC, b.booking_end ASC
');

// Stats für O(1)-Zugriff nach [begin][end] indexieren
$STAT_FIELDS = array('halle','halle_checkin','aussen','aussen_checkin','valet','valet_checkin','fahrzeuge','wait_checkin','storno');
$statsByBE = array();
foreach ($stats_be as $r) {
    $statsByBE[$r['s_begin']][$r['s_end']] = $r;
}


// ---- TAGES-ÜBERSICHT: (begin,end)-Stats in PHP auf begin aufsummieren --------
$today  = date('Y-m-d');
$dayAgg = array(); // begin => summierte Stats (Reihenfolge bleibt aufsteigend, da stats_be sortiert ist)

foreach ($stats_be as $r) {
    $bg = $r['s_begin'];
    if (!isset($dayAgg[$bg])) {
        $dayAgg[$bg] = array_fill_keys($STAT_FIELDS, 0);
    }
    foreach ($STAT_FIELDS as $f) {
        $dayAgg[$bg][$f] += (int) $r[$f];
    }
}

$arr_events = array();
foreach ($dayAgg as $bg => $stats) {
    $ts  = strtotime($bg);
    $row = array(
        'year'     => date('Y', $ts),
        'month'    => date('m', $ts),
        'day'      => date('d', $ts),
        'date'     => $bg,
        'is_today' => ($bg === $today ? 1 : 0),
    );
    // als String belassen -> identisch zur bisherigen SQL-Ausgabe (SUM liefert String)
    foreach ($STAT_FIELDS as $f) {
        $row[$f] = (string) $stats[$f];
    }
    $arr_events[] = $row;

    if ($limit > 0 && count($arr_events) >= $limit) {
        break;
    }
}


// ---- SCHIFFE: nur noch Meta (Titel/Logo/last_booking) je (begin,end,title) ---
// Die Statistik-Spalten (halle, aussen, ...) kommen nicht mehr aus einer zweiten
// Aggregation, sondern werden unten aus $statsByBE gemerged.
$ships_raw = $connection->fetchAll('
    SELECT
        b.booking_begin AS _key_date,
        b.booking_begin AS s_begin,
        b.booking_end   AS s_end,
        DATE_FORMAT(b.booking_begin, "%Y-%m-%d") AS date,
        DATE_FORMAT(b.booking_begin, "%Y/%m/%d") AS date_link,
        IF(ei.event_title IS NOT NULL, ei.event_title, b.booking_event) AS title,
        MAX(IF(ei.event_logo IS NOT NULL, ei.event_logo, "img/seaside/parken-warnemuende.png")) AS logo,
        MAX(lb.last_booking) AS last_booking,
        IF(b.booking_begin = CURDATE(), 1, 0) AS is_today
    FROM pacim_booking b
        LEFT JOIN pacim_events e
            ON e.event_calendar_begin >= b.booking_begin
            AND e.event_calendar_begin < b.booking_begin + INTERVAL 1 DAY
            AND (e.event_calendar_title = b.booking_event
                 OR (e.event_calendar_end >= b.booking_end
                     AND e.event_calendar_end < b.booking_end + INTERVAL 1 DAY))
        LEFT JOIN pacim_events_info ei ON ei.event_id = e.event_calendar_info_id
        LEFT JOIN (
            SELECT lb_begin, lb_end, last_booking FROM (
                SELECT
                    bs.booking_begin AS lb_begin,
                    bs.booking_end   AS lb_end,
                    DATE_FORMAT(isu.invoice_date, "%d.%m.%Y") AS last_booking,
                    ROW_NUMBER() OVER (
                        PARTITION BY bs.booking_begin, bs.booking_end
                        ORDER BY isu.invoice_id DESC
                    ) AS rn
                FROM pacim_booking bs
                    JOIN pacim_invoice isu ON isu.invoice_id = bs.booking_invoice
                    JOIN pacim_customer csu ON csu.customer_id = bs.booking_customer
                WHERE isu.invoice_status != 3
                    AND csu.customer_source = "Parken-am-Schiff.de"
                    AND ' . $cond_bs . '
            ) z WHERE rn = 1
        ) lb ON lb.lb_begin = b.booking_begin AND lb.lb_end = b.booking_end
    WHERE ' . $cond_b . '
    GROUP BY b.booking_begin, b.booking_end, title
    ORDER BY b.booking_begin ASC, title ASC
');

// Schiffe nach Tag gruppieren + Stats aus $statsByBE mergen
$shipsByDate = array();
foreach ($ships_raw as $row) {
    $st = isset($statsByBE[$row['s_begin']][$row['s_end']])
        ? $statsByBE[$row['s_begin']][$row['s_end']]
        : null;
    foreach ($STAT_FIELDS as $f) {
        $row[$f] = $st !== null ? $st[$f] : '0';
    }
    $shipsByDate[$row['_key_date']][] = $row;
}


$arr_items = array();
$arr_ships = array();
if($count > 0) {

	foreach($arr_events as $eventKey => $event) {

		// statt eigener Query pro Tag: vorgruppierte Schiffe holen
		$arr_ships[ $eventKey ] = isset($shipsByDate[ $event['date'] ])
			? $shipsByDate[ $event['date'] ]
			: array();

		foreach($arr_ships[ $eventKey ] as $key => $ship) {

			$arr_ships[ $eventKey ][ $key ] = array(
				'date' => $ship['date'],
				'date_link' => $ship['date_link'],
				'title' => $ship['title'],
				'logo' => $ship['logo'],
				'is_today' => $ship['is_today'],
				'last_booking' => $ship['last_booking'],
				'stats' => array(
					'fahrzeuge' => array(
						'all' => (int)$ship['fahrzeuge'],
						'wait' => (int)$ship['wait_checkin'],
						'checkin' => (int)$ship['fahrzeuge']-$ship['wait_checkin'],
						'percent' => array(
							'status' => $ship['fahrzeuge'] > 0 ? number_format( ( ( $ship['fahrzeuge']-$ship['wait_checkin'] ) / $ship['fahrzeuge'] * 100 ), 2, '.', false ) : 0,
							'rest' => $ship['fahrzeuge'] > 0 ? number_format( ( 100-( ( $ship['fahrzeuge']-$ship['wait_checkin'] ) / $ship['fahrzeuge'] * 100 ) ), 2, '.', false ) : 100
						)
					),
					'halle' => array(
						'all' => (int)$ship['halle'],
						'wait' => (int)$ship['halle']-$ship['halle_checkin'],
						'checkin' => (int)$ship['halle_checkin'],
						'percent' => array(
							'status' => $ship['halle_checkin'] > 0 && $ship['halle'] > 0 ? number_format( ( $ship['halle_checkin'] / $ship['halle'] * 100 ), 2, '.', false ) : 0,
							'rest' => $ship['halle_checkin'] > 0 && $ship['halle'] > 0 ? number_format( ( 100-$ship['halle_checkin'] / $ship['halle'] * 100 ), 2, '.', false ) : 100
						)
					),
					'aussen' => array(
						'all' => (int)$ship['aussen'],
						'wait' => (int)$ship['aussen']-$ship['aussen_checkin'],
						'checkin' => (int)$ship['aussen_checkin'],
						'percent' => array(
							'status' => $ship['aussen_checkin'] > 0 && $ship['aussen'] > 0 ? number_format( ( $ship['aussen_checkin'] / $ship['aussen'] * 100 ), 2, '.', false ) : 0,
							'rest' => $ship['aussen_checkin'] > 0 && $ship['aussen'] > 0 ? number_format( ( 100-$ship['aussen_checkin'] / $ship['aussen'] * 100 ), 2, '.', false ) : 100
						)
					),
					'valet' => array(
						'all' => (int)$ship['valet'],
						'wait' => (int)$ship['valet']-$event['valet_checkin'],
						'checkin' => (int)$ship['valet_checkin'],
						'percent' => array(
							'status' => $ship['valet_checkin'] > 0 && $ship['valet'] > 0 ? number_format( ( $ship['valet_checkin'] / $ship['valet'] * 100 ), 2, '.', false ) : 0,
							'rest' => $ship['valet_checkin'] > 0 && $ship['valet'] > 0 ? number_format( ( 100-$ship['valet_checkin'] / $ship['valet'] * 100 ), 2, '.', false ) : 100
						)
					),
					'storno' => $ship['storno']
				),
			);

			if($ship['fahrzeuge'] > 0) {
				$arr_ships[ $eventKey ][ $key ]['percent'] = number_format(($arr_ships[ $eventKey ][ $key ]['stats']['fahrzeuge']['checkin']/$ship['fahrzeuge']*100), 2, '.', '');
				$arr_ships[ $eventKey ][ $key ]['percent_rest'] = 100-$arr_ships[ $eventKey ][ $key ]['percent'];
			} else {
				$arr_ships[ $eventKey ][ $key ]['percent'] = 0;
				$arr_ships[ $eventKey ][ $key ]['percent_rest'] = 0;
			}
		}

		$arr_items[ $event['date'] ] = array(

			'calendar' => array(
				'day' => $event['day'],
				'month' => $event['month'],
				'year' => $event['year'],
				'date' => $event['date'],
				'today' => $event['is_today']
			),
			'stats' => array(
				'fahrzeuge' => array(
					'all' => $event['fahrzeuge'],
					'wait' => $event['wait_checkin'],
					'checkin' => $event['fahrzeuge']-$event['wait_checkin'],
					'percent' => array(
						'status' => $event['fahrzeuge'] > 0 ? number_format( ( ( $event['fahrzeuge']-$event['wait_checkin'] ) / $event['fahrzeuge'] * 100 ), 2, '.', false ) : 0,
						'rest' => $event['fahrzeuge'] > 0 ? number_format( ( 100-( ( $event['fahrzeuge']-$event['wait_checkin'] ) / $event['fahrzeuge'] * 100 ) ), 2, '.', false ) : 100
					)
				),
				'halle' => array(
					'all' => $event['halle'],
					'wait' => $event['halle']-$event['halle_checkin'],
					'checkin' => $event['halle_checkin'],
					'percent' => array(
						'status' => $event['halle_checkin'] > 0 && $event['halle'] > 0 ? number_format( ( $event['halle_checkin'] / $event['halle'] * 100 ), 2, '.', false ) : 0,
						'rest' => $event['halle_checkin'] > 0 && $event['halle'] > 0 ? number_format( ( 100-$event['halle_checkin'] / $event['halle'] * 100 ), 2, '.', false ) : 100
					)
				),
				'aussen' => array(
					'all' => $event['aussen'],
					'wait' => $event['aussen']-$event['aussen_checkin'],
					'checkin' => $event['aussen_checkin'],
					'percent' => array(
						'status' => $event['aussen_checkin'] > 0 && $event['aussen'] > 0 ? number_format( ( $event['aussen_checkin'] / $event['aussen'] * 100 ), 2, '.', false ) : 0,
						'rest' => $event['aussen_checkin'] > 0 && $event['aussen'] > 0 ? number_format( ( 100-$event['aussen_checkin'] / $event['aussen'] * 100 ), 2, '.', false ) : 100
					)
				),
				'valet' => array(
					'all' => $event['valet'],
					'wait' => $event['valet']-$event['valet_checkin'],
					'checkin' => $event['valet_checkin'],
					'percent' => array(
						'status' => $event['valet_checkin'] > 0 && $event['valet'] > 0 ? number_format( ( $event['valet_checkin'] / $event['valet'] * 100 ), 2, '.', false ) : 0,
						'rest' => $event['valet_checkin'] > 0 && $event['valet'] > 0 ? number_format( ( 100-$event['valet_checkin'] / $event['valet'] * 100 ), 2, '.', false ) : 100
					)
				),
				'storno' => $event['storno']
			),
			'ships' => $arr_ships[ $eventKey ]
		);

	}

}

$payload = array(
	'status' => 'success',
	'count' => $count,
	'connection' => API_CONNECTION,
	'entries' => $arr_items
);

if ($cacheTtl > 0) {
	$cache->set($cacheKey, $payload, $cacheTtl);
}

return $response->build(200, [], $payload);

Youez - 2016 - github.com/yon3zu
LinuXploit