- Implemented a new Banner model to represent banner data. - Created a BannerRepository for database interactions related to banners. - Developed a BannerService to handle business logic for banners. - Added admin views for listing and adding banners. - Integrated banner hooks for frontend rendering and click tracking. - Created frontend styles and scripts for banner display and interaction. - Updated database migrations to include a new banners table. - Enhanced AdminController to manage banner actions and pages.
112 lines
3.1 KiB
PHP
112 lines
3.1 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) {
|
|
return 'sodino_active_banners_' . md5($position . '|' . serialize($context));
|
|
}
|
|
}
|