Files
sodino/app/Services/BannerService.php

124 lines
3.7 KiB
PHP

<?php
namespace Sodino\Services;
use Sodino\Models\Banner;
use Sodino\Repositories\BannerRepository;
/**
* Banner Service
*/
class BannerService {
private $repository;
public function __construct(BannerRepository $repository) {
$this->repository = $repository;
}
public function getActiveBanners(array $context = []) {
$position = $context['position'] ?? '';
$cache_key = $this->getCacheKey($position, $context);
$banners = wp_cache_get($cache_key, 'sodino_banners');
if ($banners === false) {
$banners = array_filter($this->repository->getEnabled(), function (Banner $banner) use ($context) {
return $this->filterByPosition($banner, $context)
&& $this->filterByTime($banner)
&& $this->filterByUserType($banner)
&& $this->filterByDevice($banner);
});
usort($banners, function (Banner $a, Banner $b) {
return $b->priority <=> $a->priority;
});
wp_cache_set($cache_key, $banners, 'sodino_banners', MINUTE_IN_SECONDS);
}
$limit = isset($context['limit']) ? (int) $context['limit'] : 1;
return $limit > 0 ? array_slice($banners, 0, $limit) : $banners;
}
public function filterByTime(Banner $banner) {
$now = current_time('timestamp');
if (!empty($banner->start_time)) {
$start = strtotime($banner->start_time);
if ($start !== false && $now < $start) {
return false;
}
}
if (!empty($banner->end_time)) {
$end = strtotime($banner->end_time);
if ($end !== false && $now > $end) {
return false;
}
}
return true;
}
public function filterByUserType(Banner $banner) {
if ($banner->user_target === 'all') {
return true;
}
$userType = is_user_logged_in() ? 'returning' : 'new';
return $banner->user_target === $userType;
}
public function filterByDevice(Banner $banner) {
if ($banner->device_target === 'all') {
return true;
}
$device = wp_is_mobile() ? 'mobile' : 'desktop';
return $banner->device_target === $device;
}
public function filterByPosition(Banner $banner, array $context) {
if (empty($context['position'])) {
return false;
}
if ($banner->position !== $context['position']) {
return false;
}
if ($banner->position === 'product_page' && !is_singular('product')) {
return false;
}
if ($banner->position === 'cart' && !is_cart()) {
return false;
}
return true;
}
public function increaseImpression($bannerId) {
$this->repository->incrementImpression($bannerId);
}
public function increaseClick($bannerId) {
$this->repository->incrementClick($bannerId);
}
private function getCacheKey($position, array $context) {
$version = wp_cache_get('version', 'sodino_banners');
if ($version === false) {
$version = get_option('sodino_banners_cache_version', 1);
wp_cache_set('version', $version, 'sodino_banners');
}
$runtimeContext = [
'user' => is_user_logged_in() ? 'returning' : 'new',
'device' => wp_is_mobile() ? 'mobile' : 'desktop',
'minute' => gmdate('YmdHi', current_time('timestamp', true)),
];
return 'sodino_active_banners_' . md5($version . '|' . $position . '|' . wp_json_encode($context) . '|' . wp_json_encode($runtimeContext));
}
}