feat: Add banner management functionality
- 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.
This commit is contained in:
111
app/Services/BannerService.php
Normal file
111
app/Services/BannerService.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user