view_time ?? 0; } public static function byZoneAddress(Zone $zone, string $ipAddress): ?self { $getZoneView = DB::prepare(' SELECT `zone_id`, UNIX_TIMESTAMP(`view_time`) AS `view_time`, INET6_NTOA(`view_address`) AS `view_address` FROM `ytkns_zones_views` WHERE `zone_id` = :zone AND `view_address` = INET6_ATON(:ip) '); $getZoneView->bindValue('zone', $zone->getId()); $getZoneView->bindValue('ip', $ipAddress); $zoneView = $getZoneView->execute() ? $getZoneView->fetchObject(self::class) : false; return $zoneView ? $zoneView : null; } public static function increment(Zone $zone, string $ipAddress): void { $zoneView = self::byZoneAddress($zone, $ipAddress); if($zoneView !== null && ($zoneView->getTime() + self::THRESHOLD) > time()) return; $updateZoneView = DB::prepare(' REPLACE INTO `ytkns_zones_views` ( `view_address`, `zone_id`, `view_time` ) VALUES ( INET6_ATON(:ip), :zone, NOW() ) '); $updateZoneView->bindValue('ip', $ipAddress); $updateZoneView->bindValue('zone', $zone->getId()); if($updateZoneView->execute()) $zone->incrementViews(); } }