Files
sodino/public/hooks/banner-hooks.php

230 lines
7.1 KiB
PHP

<?php
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
use Sodino\Repositories\BannerRepository;
use Sodino\Services\BannerService;
global $sodino_banner_service;
$bannerRepository = new BannerRepository();
$sodino_banner_service = new BannerService($bannerRepository);
add_action('wp_body_open', 'sodino_render_top_banner', 5);
add_action('wp_footer', 'sodino_render_top_banner_fallback', 5);
add_filter('the_content', 'sodino_render_middle_banner');
add_action('wp_footer', 'sodino_render_bottom_banner', 20);
add_action('woocommerce_after_single_product_summary', 'sodino_render_product_banner', 5);
add_action('woocommerce_before_cart', 'sodino_render_cart_banner');
add_action('wp_enqueue_scripts', 'sodino_enqueue_banner_assets');
add_action('wp_ajax_nopriv_sodino_banner_click', 'sodino_handle_banner_click');
add_action('wp_ajax_sodino_banner_click', 'sodino_handle_banner_click');
add_action('woocommerce_checkout_create_order', 'sodino_add_banner_order_meta', 20, 2);
function sodino_enqueue_banner_assets() {
if (is_admin()) {
return;
}
wp_register_style('sodino-banner-frontend', plugin_dir_url(__FILE__) . '../css/banner-frontend.css', [], SODINO_VERSION);
wp_enqueue_style('sodino-banner-frontend');
wp_register_script('sodino-banner-frontend', plugin_dir_url(__FILE__) . '../js/banner-frontend.js', [], SODINO_VERSION, true);
wp_localize_script('sodino-banner-frontend', 'sodinoBannerFrontend', [
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('sodino_banner_click'),
]);
wp_enqueue_script('sodino-banner-frontend');
}
function sodino_get_banner_html($banner) {
global $sodino_banner_service;
$html = '';
$content = '';
switch ($banner->content_type) {
case 'image':
$image = esc_url($banner->content_value);
$image_html = '<img src="' . $image . '" alt="' . esc_attr($banner->title) . '" class="sodino-banner-image" />';
if (!empty($banner->link_url)) {
$content = sprintf('<a href="%s" class="sodino-banner-link" data-banner-id="%d">%s</a>', esc_url($banner->link_url), esc_attr($banner->id), $image_html);
} else {
$content = $image_html;
}
break;
case 'shortcode':
$content = do_shortcode(wp_kses_post($banner->content_value));
break;
case 'html':
default:
$content = wp_kses_post($banner->content_value);
break;
}
$linkAttributes = '';
if (!empty($banner->link_url) && $banner->content_type !== 'image') {
$linkAttributes = sprintf(' data-banner-id="%d" href="%s" class="sodino-banner-link"', esc_attr($banner->id), esc_url($banner->link_url));
}
$closeButton = '<button type="button" class="sodino-banner-close" aria-label="'.esc_attr__('بستن بنر', 'sodino').'" title="'.esc_attr__('بستن بنر', 'sodino').'">&times;</button>';
$wrapperClass = 'sodino-banner-wrap sodino-banner-' . esc_attr($banner->display_type) . ' sodino-banner-position-' . esc_attr($banner->position);
$style = $banner->display_type === 'popup' ? 'style="display:none;"' : '';
if ($banner->display_type === 'popup') {
$html .= '<div class="sodino-banner-backdrop" data-banner-backdrop="' . esc_attr($banner->id) . '" style="display:none;"></div>';
}
$html .= '<div class="' . $wrapperClass . '" data-banner-id="' . esc_attr($banner->id) . '" role="region" aria-label="' . esc_attr($banner->title) . '" ' . $style . '>';
$html .= $closeButton;
$html .= '<div class="sodino-banner-content">';
if ($banner->content_type !== 'image' && !empty($banner->link_url)) {
$html .= '<a' . $linkAttributes . '>' . $content . '</a>';
} else {
$html .= $content;
}
$html .= '</div>';
$html .= '</div>';
return $html;
}
function sodino_render_banner_position($position) {
global $sodino_banner_service;
if (!isset($sodino_banner_service)) {
return '';
}
$banners = $sodino_banner_service->getActiveBanners(['position' => $position, 'limit' => 1]);
if (empty($banners)) {
return '';
}
$banner = reset($banners);
$sodino_banner_service->increaseImpression($banner->id);
return sodino_get_banner_html($banner);
}
function sodino_render_top_banner() {
static $rendered = false;
if (is_admin()) {
return;
}
if ($rendered) {
return;
}
$rendered = true;
echo sodino_render_banner_position('top');
}
function sodino_render_top_banner_fallback() {
if (did_action('wp_body_open')) {
return;
}
sodino_render_top_banner();
}
function sodino_render_middle_banner($content) {
if (is_admin() || !is_singular() || !in_the_loop() || is_feed()) {
return $content;
}
$banner = sodino_render_banner_position('middle');
if (empty($banner)) {
return $content;
}
return $banner . $content;
}
function sodino_render_bottom_banner() {
if (is_admin()) {
return;
}
echo sodino_render_banner_position('bottom');
}
function sodino_render_product_banner() {
if (is_admin()) {
return;
}
echo sodino_render_banner_position('product_page');
}
function sodino_render_cart_banner() {
if (is_admin()) {
return;
}
echo sodino_render_banner_position('cart');
}
function sodino_handle_banner_click() {
$nonce = isset($_POST['nonce'])
? sanitize_text_field(wp_unslash($_POST['nonce']))
: (isset($_POST['security']) ? sanitize_text_field(wp_unslash($_POST['security'])) : '');
if (!isset($_POST['banner_id']) || !wp_verify_nonce($nonce, 'sodino_banner_click')) {
wp_send_json_error();
}
$bannerId = absint(wp_unslash($_POST['banner_id']));
if (!$bannerId) {
wp_send_json_error();
}
global $sodino_banner_service;
if (!isset($sodino_banner_service)) {
wp_send_json_error();
}
$sodino_banner_service->increaseClick($bannerId);
sodino_remember_banner_click($bannerId);
wp_send_json_success();
}
function sodino_remember_banner_click($bannerId) {
if (!function_exists('WC') || !WC()->session) {
return;
}
$clicks = WC()->session->get('sodino_banner_clicks', []);
if (!is_array($clicks)) {
$clicks = [];
}
$clicks[(int) $bannerId] = current_time('timestamp');
WC()->session->set('sodino_banner_clicks', $clicks);
}
function sodino_add_banner_order_meta($order, $data) {
if (!function_exists('WC') || !WC()->session || !$order) {
return;
}
$clicks = WC()->session->get('sodino_banner_clicks', []);
if (empty($clicks) || !is_array($clicks)) {
return;
}
$validClicks = [];
$cutoff = current_time('timestamp') - DAY_IN_SECONDS;
foreach ($clicks as $bannerId => $timestamp) {
if ((int) $bannerId > 0 && (int) $timestamp >= $cutoff) {
$validClicks[] = (int) $bannerId;
}
}
if (empty($validClicks)) {
return;
}
$order->update_meta_data('_sodino_banner_click_ids', implode(',', array_values(array_unique($validClicks))));
WC()->session->__unset('sodino_banner_clicks');
}