Skip to content

Instantly share code, notes, and snippets.

@JusTruetice
Created August 21, 2025 10:44
Show Gist options
  • Select an option

  • Save JusTruetice/579c34a5ef52b1695cc4445412e1a47d to your computer and use it in GitHub Desktop.

Select an option

Save JusTruetice/579c34a5ef52b1695cc4445412e1a47d to your computer and use it in GitHub Desktop.
Wordpress old version function.php main
<?php
/**
* Theme functions and definitions
*
* @package HelloElementor
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
define( 'HELLO_ELEMENTOR_VERSION', '3.1.1' );
if ( ! isset( $content_width ) ) {
$content_width = 800; // Pixels.
}
if ( ! function_exists( 'hello_elementor_setup' ) ) {
/**
* Set up theme support.
*
* @return void
*/
function hello_elementor_setup() {
if ( is_admin() ) {
hello_maybe_update_theme_version_in_db();
}
if ( apply_filters( 'hello_elementor_register_menus', true ) ) {
register_nav_menus( [ 'menu-1' => esc_html__( 'Header', 'hello-elementor' ) ] );
register_nav_menus( [ 'menu-2' => esc_html__( 'Footer', 'hello-elementor' ) ] );
}
if ( apply_filters( 'hello_elementor_post_type_support', true ) ) {
add_post_type_support( 'page', 'excerpt' );
}
if ( apply_filters( 'hello_elementor_add_theme_support', true ) ) {
add_theme_support( 'post-thumbnails' );
add_theme_support( 'automatic-feed-links' );
add_theme_support( 'title-tag' );
add_theme_support(
'html5',
[
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
'script',
'style',
]
);
add_theme_support(
'custom-logo',
[
'height' => 100,
'width' => 350,
'flex-height' => true,
'flex-width' => true,
]
);
/*
* Editor Style.
*/
add_editor_style( 'classic-editor.css' );
/*
* Gutenberg wide images.
*/
add_theme_support( 'align-wide' );
/*
* WooCommerce.
*/
if ( apply_filters( 'hello_elementor_add_woocommerce_support', true ) ) {
// WooCommerce in general.
add_theme_support( 'woocommerce' );
// Enabling WooCommerce product gallery features (are off by default since WC 3.0.0).
// zoom.
add_theme_support( 'wc-product-gallery-zoom' );
// lightbox.
add_theme_support( 'wc-product-gallery-lightbox' );
// swipe.
add_theme_support( 'wc-product-gallery-slider' );
}
}
}
}
add_action( 'after_setup_theme', 'hello_elementor_setup' );
function hello_maybe_update_theme_version_in_db() {
$theme_version_option_name = 'hello_theme_version';
// The theme version saved in the database.
$hello_theme_db_version = get_option( $theme_version_option_name );
// If the 'hello_theme_version' option does not exist in the DB, or the version needs to be updated, do the update.
if ( ! $hello_theme_db_version || version_compare( $hello_theme_db_version, HELLO_ELEMENTOR_VERSION, '<' ) ) {
update_option( $theme_version_option_name, HELLO_ELEMENTOR_VERSION );
}
}
if ( ! function_exists( 'hello_elementor_display_header_footer' ) ) {
/**
* Check whether to display header footer.
*
* @return bool
*/
function hello_elementor_display_header_footer() {
$hello_elementor_header_footer = true;
return apply_filters( 'hello_elementor_header_footer', $hello_elementor_header_footer );
}
}
if ( ! function_exists( 'hello_elementor_scripts_styles' ) ) {
/**
* Theme Scripts & Styles.
*
* @return void
*/
function hello_elementor_scripts_styles() {
$min_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
if ( apply_filters( 'hello_elementor_enqueue_style', true ) ) {
wp_enqueue_style(
'hello-elementor',
get_template_directory_uri() . '/style' . $min_suffix . '.css',
[],
HELLO_ELEMENTOR_VERSION
);
}
if ( apply_filters( 'hello_elementor_enqueue_theme_style', true ) ) {
wp_enqueue_style(
'hello-elementor-theme-style',
get_template_directory_uri() . '/theme' . $min_suffix . '.css',
[],
HELLO_ELEMENTOR_VERSION
);
}
if ( hello_elementor_display_header_footer() ) {
wp_enqueue_style(
'hello-elementor-header-footer',
get_template_directory_uri() . '/header-footer' . $min_suffix . '.css',
[],
HELLO_ELEMENTOR_VERSION
);
}
}
}
add_action( 'wp_enqueue_scripts', 'hello_elementor_scripts_styles' );
if ( ! function_exists( 'hello_elementor_register_elementor_locations' ) ) {
/**
* Register Elementor Locations.
*
* @param ElementorPro\Modules\ThemeBuilder\Classes\Locations_Manager $elementor_theme_manager theme manager.
*
* @return void
*/
function hello_elementor_register_elementor_locations( $elementor_theme_manager ) {
if ( apply_filters( 'hello_elementor_register_elementor_locations', true ) ) {
$elementor_theme_manager->register_all_core_location();
}
}
}
add_action( 'elementor/theme/register_locations', 'hello_elementor_register_elementor_locations' );
if ( ! function_exists( 'hello_elementor_content_width' ) ) {
/**
* Set default content width.
*
* @return void
*/
function hello_elementor_content_width() {
$GLOBALS['content_width'] = apply_filters( 'hello_elementor_content_width', 800 );
}
}
add_action( 'after_setup_theme', 'hello_elementor_content_width', 0 );
if ( ! function_exists( 'hello_elementor_add_description_meta_tag' ) ) {
/**
* Add description meta tag with excerpt text.
*
* @return void
*/
function hello_elementor_add_description_meta_tag() {
if ( ! apply_filters( 'hello_elementor_description_meta_tag', true ) ) {
return;
}
if ( ! is_singular() ) {
return;
}
$post = get_queried_object();
if ( empty( $post->post_excerpt ) ) {
return;
}
echo '<meta name="description" content="' . esc_attr( wp_strip_all_tags( $post->post_excerpt ) ) . '">' . "\n";
}
}
add_action( 'wp_head', 'hello_elementor_add_description_meta_tag' );
// Admin notice
if ( is_admin() ) {
require get_template_directory() . '/includes/admin-functions.php';
}
// Settings page
require get_template_directory() . '/includes/settings-functions.php';
// Header & footer styling option, inside Elementor
require get_template_directory() . '/includes/elementor-functions.php';
if ( ! function_exists( 'hello_elementor_customizer' ) ) {
// Customizer controls
function hello_elementor_customizer() {
if ( ! is_customize_preview() ) {
return;
}
if ( ! hello_elementor_display_header_footer() ) {
return;
}
require get_template_directory() . '/includes/customizer-functions.php';
}
}
add_action( 'init', 'hello_elementor_customizer' );
if ( ! function_exists( 'hello_elementor_check_hide_title' ) ) {
/**
* Check whether to display the page title.
*
* @param bool $val default value.
*
* @return bool
*/
function hello_elementor_check_hide_title( $val ) {
if ( defined( 'ELEMENTOR_VERSION' ) ) {
$current_doc = Elementor\Plugin::instance()->documents->get( get_the_ID() );
if ( $current_doc && 'yes' === $current_doc->get_settings( 'hide_title' ) ) {
$val = false;
}
}
return $val;
}
}
add_filter( 'hello_elementor_page_title', 'hello_elementor_check_hide_title' );
/**
* BC:
* In v2.7.0 the theme removed the `hello_elementor_body_open()` from `header.php` replacing it with `wp_body_open()`.
* The following code prevents fatal errors in child themes that still use this function.
*/
if ( ! function_exists( 'hello_elementor_body_open' ) ) {
function hello_elementor_body_open() {
wp_body_open();
}
}
/* category item element */
function register_custom_category_widget($widgets_manager) {
class Custom_Category_Element extends \Elementor\Widget_Base {
public function get_name() {
return 'new_category';
}
public function get_title() {
return esc_html__('New Category', 'textdomain');
}
public function get_icon() {
return 'eicon-folder';
}
public function get_categories() {
return ['basic'];
}
public function get_script_depends() {
return ['swiper-js'];
}
public function get_style_depends() {
return ['swiper-css'];
}
protected function register_controls() {
$this->start_controls_section(
'content_section',
[
'label' => esc_html__('Content Settings', 'textdomain'),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]
);
$product_categories = get_terms([
'taxonomy' => 'product_cat',
'hide_empty' => false,
]);
$categories_options = [];
foreach ($product_categories as $category) {
$categories_options[$category->term_id] = $category->name;
}
$this->add_control(
'selected_categories',
[
'label' => esc_html__('Select Categories', 'textdomain'),
'type' => \Elementor\Controls_Manager::SELECT2,
'multiple' => true,
'options' => $categories_options,
'default' => [],
]
);
$this->add_control(
'columns_desktop',
[
'label' => esc_html__('Desktop Columns', 'textdomain'),
'type' => \Elementor\Controls_Manager::SELECT,
'default' => '4',
'options' => [
'2' => '2',
'3' => '3',
'4' => '4',
'6' => '6'
],
]
);
$this->add_control(
'carousel_settings',
[
'label' => esc_html__('Carousel Settings', 'textdomain'),
'type' => \Elementor\Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'show_navigation',
[
'label' => esc_html__('Show Navigation', 'textdomain'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => esc_html__('Yes', 'textdomain'),
'label_off' => esc_html__('No', 'textdomain'),
'default' => 'yes',
]
);
$this->add_control(
'show_pagination',
[
'label' => esc_html__('Show Pagination', 'textdomain'),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => esc_html__('Yes', 'textdomain'),
'label_off' => esc_html__('No', 'textdomain'),
'default' => 'yes',
]
);
$this->end_controls_section();
$this->start_controls_section(
'style_section',
[
'label' => esc_html__('Style Settings', 'textdomain'),
'tab' => \Elementor\Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'background_color',
[
'label' => esc_html__('Background Color', 'textdomain'),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#191919',
'selectors' => [
'{{WRAPPER}} .category-item' => 'background-color: {{VALUE}}'
],
]
);
$this->add_control(
'text_color',
[
'label' => esc_html__('Text Color', 'textdomain'),
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#ffffff',
'selectors' => [
'{{WRAPPER}} .category-title' => 'color: {{VALUE}}'
],
]
);
$this->end_controls_section();
}
public function __construct($data = [], $args = null) {
parent::__construct($data, $args);
wp_register_script(
'swiper-js',
'https://unpkg.com/swiper/swiper-bundle.min.js',
[],
'8.4.5',
true
);
wp_register_style(
'swiper-css',
'https://unpkg.com/swiper/swiper-bundle.min.css',
[],
'8.4.5'
);
}
protected function render() {
$settings = $this->get_settings_for_display();
$selected_categories = $settings['selected_categories'];
if (empty($selected_categories)) {
echo esc_html__('Please select categories to display', 'textdomain');
return;
}
$args = array(
'taxonomy' => 'product_cat',
'hide_empty' => false,
'include' => $selected_categories,
'orderby' => 'include'
);
$categories = get_terms($args);
if (!empty($categories)) {
wp_enqueue_script('jquery');
$widget_id = $this->get_id();
?>
<style>
.custom-category-grid {
display: grid;
grid-template-columns: repeat(<?php echo esc_attr($settings['columns_desktop']); ?>, 1fr);
gap: 20px;
padding: 20px;
}
.category-item {
position: relative;
overflow: hidden;
transition: all 0.3s ease;
padding: 20px;
text-align: center;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
background-color: <?php echo esc_attr($settings['background_color']); ?>;
}
.category-title {
font-size: 18px;
font-weight: 600;
margin: 0;
padding: 10px 0;
color: <?php echo esc_attr($settings['text_color']); ?>;
}
.category-image {
margin-top: 15px;
position: relative;
padding-bottom: 56.25%;
max-height: 200px;
}
.category-image img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: contain;
}
.view-more {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: #F6AB2F;
color: #fff;
padding: 15px;
opacity: 0;
transform: translateY(100%);
transition: all 0.3s ease;
text-align: center;
font-weight: 500;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
text-decoration: none;
}
.category-item:hover .view-more {
opacity: 1;
transform: translateY(0);
}
.view-more svg {
width: 16px;
height: 16px;
transform: rotate(45deg);
}
@media (min-width: 768px) {
.mobile-carousel {
display: none;
}
}
@media (max-width: 767px) {
.custom-category-grid {
display: none;
}
.mobile-carousel {
display: block;
padding: 10px;
}
.mobile-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.category-item {
height: auto;
padding: 10px;
margin: 0;
}
.category-title {
font-size: 14px;
padding: 5px 0;
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.2;
}
.category-image {
margin-top: 8px;
padding-bottom: 60%;
}
.view-more {
opacity: 0;
transform: translateY(100%);
padding: 8px;
font-size: 13px;
}
.category-item.active .view-more {
opacity: 1;
transform: translateY(0);
}
.view-more svg {
width: 14px;
height: 14px;
}
}
@media (max-width: 359px) {
.category-title {
font-size: 13px;
}
.view-more {
font-size: 12px;
padding: 6px;
}
}
</style>
<!-- Desktop Grid -->
<div class="custom-category-grid">
<?php foreach ($categories as $category) :
$thumbnail_id = get_term_meta($category->term_id, 'thumbnail_id', true);
$image = wp_get_attachment_url($thumbnail_id);
// Get current language
$current_lang = function_exists('wpml_get_current_language') ? wpml_get_current_language() : '';
// Используем прямую ссылку на категорию WooCommerce
$category_link = get_term_link($category->term_id, 'product_cat');
// Set text based on current language
$view_more_text = $current_lang === 'en' ? 'MORE' : 'სრულად ნახვა';
?>
<div class="category-item">
<h3 class="category-title"><?php echo esc_html($category->name); ?></h3>
<?php if ($image) : ?>
<div class="category-image">
<img src="<?php echo esc_url($image); ?>" alt="<?php echo esc_attr($category->name); ?>" loading="lazy">
</div>
<?php endif; ?>
<a href="<?php echo esc_url($category_link); ?>"
class="view-more"
data-category-id="<?php echo esc_attr($category->term_id); ?>">
<?php echo esc_html($view_more_text); ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M5 12h14M12 5l7 7-7 7"/>
</svg>
</a>
</div>
<?php endforeach; ?>
</div>
<!-- Mobile Grid -->
<div class="mobile-carousel">
<div class="mobile-grid">
<?php foreach ($categories as $category) :
$thumbnail_id = get_term_meta($category->term_id, 'thumbnail_id', true);
$image = wp_get_attachment_url($thumbnail_id);
// Get current language
$current_lang = function_exists('wpml_get_current_language') ? wpml_get_current_language() : '';
// Используем прямую ссылку на категорию WooCommerce
$category_link = get_term_link($category->term_id, 'product_cat');
// Set text based on current language
$view_more_text = $current_lang === 'en' ? 'MORE' : 'სრულად ნახვა';
?>
<div class="category-item">
<h3 class="category-title"><?php echo esc_html($category->name); ?></h3>
<?php if ($image) : ?>
<div class="category-image">
<img src="<?php echo esc_url($image); ?>" alt="<?php echo esc_attr($category->name); ?>" loading="lazy">
</div>
<?php endif; ?>
<a href="<?php echo esc_url($category_link); ?>"
class="view-more"
data-category-id="<?php echo esc_attr($category->term_id); ?>">
<?php echo esc_html($view_more_text); ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M5 12h14M12 5l7 7-7 7"/>
</svg>
</a>
</div>
<?php endforeach; ?>
</div>
</div>
<script>
jQuery(document).ready(function($) {
// Mobile category item click handler
$('.mobile-carousel .category-item').on('click', function(e) {
if (!$(e.target).hasClass('view-more') && !$(e.target).closest('.view-more').length) {
$(this).addClass('active');
// Remove active class from other items
$('.mobile-carousel .category-item').not(this).removeClass('active');
}
});
// Update links when language is switched
$(document).on('wpml_language_switched', function(event, data) {
var newLang = data.to;
var viewMoreText = newLang === 'en' ? 'MORE' : 'სრულად ნახვა';
// Update text for view more buttons
$('.view-more').each(function() {
// Сохраняем только текст, без затрагивания дочерних элементов
$(this).contents().filter(function() {
return this.nodeType === 3; // Текстовые узлы
}).first().replaceWith(viewMoreText);
});
});
});
</script><?php
}
}
}
$widgets_manager->register(new Custom_Category_Element());
}
add_action('elementor/widgets/register', 'register_custom_category_widget');
add_shortcode('product_stock_status', 'show_product_stock_status');
function show_product_stock_status() {
global $product;
if (!$product) return '';
$stock_status = $product->get_stock_status();
// Default Georgian text
$in_stock_text = 'მარაგშია';
$out_of_stock_text = 'არ არის მარაგში';
// Check if WPML functions exist and get current language
if (function_exists('icl_object_id')) {
$current_language = apply_filters('wpml_current_language', NULL);
if ($current_language == 'en') {
$in_stock_text = 'In Stock';
$out_of_stock_text = 'Out of Stock';
}
}
if ($stock_status == 'instock') {
return '<span style="color: green;">' . $in_stock_text . '</span>';
} else {
return '<span style="color: red;">' . $out_of_stock_text . '</span>';
}
}
// Регистрация виджета Elementor для бейджа WooCommerce
add_action('elementor/widgets/widgets_registered', function ($widgets_manager) {
class WooCommerce_Discount_Badge_Widget extends \Elementor\Widget_Base {
public function get_name() {
return 'woocommerce_discount_badge';
}
public function get_title() {
return __('WooCommerce Discount Badge', 'text-domain');
}
public function get_icon() {
return 'eicon-products';
}
public function get_categories() {
return ['woocommerce-elements'];
}
protected function render() {
// Получение текущего продукта WooCommerce
global $product;
// Если продукт не найден или не в распродаже — ничего не выводить
if (!$product || !$product->is_on_sale()) {
return; // Ничего не делаем
}
// Получение цен продукта
$regular_price = $product->get_regular_price(); // Старая цена
$sale_price = $product->get_sale_price(); // Цена со скидкой
// Проверка наличия цен и расчет процента скидки
if ($regular_price && $sale_price) {
$discount_percentage = round((($regular_price - $sale_price) / $regular_price) * 100);
// Вывод бейджа
echo '<div class="custom-discount-badge">-' . $discount_percentage . '%</div>';
}
}
}
$widgets_manager->register_widget_type(new WooCommerce_Discount_Badge_Widget());
});
// Add form wrapper and styles
add_action('wp_head', 'add_registration_form_styles');
function add_registration_form_styles() {
?>
<style>
.registration-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
margin-bottom: 20px;
}
.registration-grid .woocommerce-form-row {
margin: 0 !important;
}
.registration-grid input {
background-color: #f8f9fa !important;
border: none !important;
padding: 10px !important;
width: 100% !important;
}
.registration-grid .form-row-full {
grid-column: 1 / -1;
}
.form-row-full input {
width: 100% !important;
}
.woocommerce-privacy-policy-text {
grid-column: 1 / -1;
margin-top: 10px;
color: #666;
font-size: 14px;
}
@media (max-width: 768px) {
.registration-grid {
grid-template-columns: 1fr;
}
}
</style>
<?php
}
// Add custom fields to registration form
add_action('woocommerce_register_form_start', 'add_custom_registration_fields_start');
function add_custom_registration_fields_start() {
echo '<div class="registration-grid">';
}
add_action('woocommerce_register_form', 'add_custom_registration_fields');
function add_custom_registration_fields() {
?>
<p class="woocommerce-form-row form-row">
<label for="reg_billing_first_name"><?php _e('სახელი', 'woocommerce'); ?> <span class="required">*</span></label>
<input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="billing_first_name" id="reg_billing_first_name" required />
</p>
<p class="woocommerce-form-row form-row">
<label for="reg_billing_last_name"><?php _e('გვარი', 'woocommerce'); ?> <span class="required">*</span></label>
<input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="billing_last_name" id="reg_billing_last_name" required />
</p>
<p class="woocommerce-form-row form-row">
<label for="reg_billing_phone"><?php _e('ტელეფონი', 'woocommerce'); ?> <span class="required">*</span></label>
<input type="tel" class="woocommerce-Input woocommerce-Input--text input-text" name="billing_phone" id="reg_billing_phone" required />
</p>
<p class="woocommerce-form-row form-row">
<label for="reg_password"><?php _e('პაროლი', 'woocommerce'); ?> <span class="required">*</span></label>
<input type="password" class="woocommerce-Input woocommerce-Input--text input-text" name="password" id="reg_password" autocomplete="new-password" required />
</p>
<?php
}
add_action('woocommerce_register_form_end', 'add_custom_registration_fields_end');
function add_custom_registration_fields_end() {
echo '</div>';
}
// Validate fields and set password
add_filter('woocommerce_registration_errors', 'validate_custom_registration_fields', 10, 3);
function validate_custom_registration_fields($errors, $username, $email) {
if (empty($_POST['billing_first_name'])) {
$errors->add('billing_first_name_error', __('გთხოვთ შეიყვანოთ სახელი', 'woocommerce'));
}
if (empty($_POST['billing_last_name'])) {
$errors->add('billing_last_name_error', __('გთხოვთ შეიყვანოთ გვარი', 'woocommerce'));
}
if (empty($_POST['billing_phone'])) {
$errors->add('billing_phone_error', __('გთხოვთ შეიყვანოთ ტელეფონის ნომერი', 'woocommerce'));
}
if (empty($_POST['password'])) {
$errors->add('password_error', __('გთხოვთ შეიყვანოთ პაროლი', 'woocommerce'));
}
return $errors;
}
// Save fields and set password
add_action('woocommerce_created_customer', 'save_custom_registration_fields');
function save_custom_registration_fields($customer_id) {
// Save custom fields
if (isset($_POST['billing_first_name'])) {
update_user_meta($customer_id, 'billing_first_name', sanitize_text_field($_POST['billing_first_name']));
update_user_meta($customer_id, 'first_name', sanitize_text_field($_POST['billing_first_name']));
}
if (isset($_POST['billing_last_name'])) {
update_user_meta($customer_id, 'billing_last_name', sanitize_text_field($_POST['billing_last_name']));
update_user_meta($customer_id, 'last_name', sanitize_text_field($_POST['billing_last_name']));
}
if (isset($_POST['billing_phone'])) {
update_user_meta($customer_id, 'billing_phone', sanitize_text_field($_POST['billing_phone']));
}
// Set user password
if (isset($_POST['password']) && !empty($_POST['password'])) {
wp_set_password($_POST['password'], $customer_id);
}
}
// Enable password field in registration
add_filter('woocommerce_registration_generate_password', '__return_false');
function display_product_brand_shortcode() {
global $product;
// Проверяем, существует ли объект $product и метод get_id()
if ( ! is_object($product) || ! method_exists($product, 'get_id') ) {
return ''; // Возвращаем пустую строку, если объект недоступен
}
// Получаем термины (бренд) для текущего продукта
$terms = wp_get_post_terms($product->get_id(), 'pa_brand');
// Проверяем, есть ли термины и нет ли ошибок
if (!empty($terms) && !is_wp_error($terms)) {
// Set the label based on current language
$brand_label = 'ბრენდი: '; // Default Georgian
// Check if WPML functions exist and get current language
if (function_exists('icl_object_id')) {
$current_language = apply_filters('wpml_current_language', NULL);
if ($current_language == 'en') {
$brand_label = 'Brand: ';
}
}
return '<p><strong>' . $brand_label . '</strong>' . esc_html($terms[0]->name) . '</p>';
}
return ''; // Возвращаем пустую строку, если бренды не найдены
}
add_shortcode('product_brand', 'display_product_brand_shortcode');
// Кнопка "ყიდვა" (Покупка)
function black_button_shortcode() {
global $product;
if (!$product) {
return '';
}
$product_id = $product->get_id();
$checkout_url = wc_get_checkout_url();
// Get the current language and set button text accordingly
$button_text = 'ყიდვა'; // Default Georgian
if (function_exists('icl_object_id')) {
$current_language = apply_filters('wpml_current_language', NULL);
if ($current_language == 'en') {
$button_text = 'Buy';
}
}
return '<a href="#" class="black-button" onclick="addToCartAndRedirect(' . $product_id . ', \'' . $checkout_url . '\'); return false;">' . $button_text . '</a>';
}
add_shortcode('black_button', 'black_button_shortcode');
// Кнопка "განვადება" (Рассрочка)
function red_button_shortcode() {
global $product;
if (!$product) {
return '';
}
$product_id = $product->get_id();
$checkout_url = wc_get_checkout_url();
// Get the current language and set button text accordingly
$button_text = 'განვადება'; // Default Georgian
if (function_exists('icl_object_id')) {
$current_language = apply_filters('wpml_current_language', NULL);
if ($current_language == 'en') {
$button_text = 'Installment';
}
}
return '<a href="#" class="red-button" onclick="addToCartAndRedirect(' . $product_id . ', \'' . $checkout_url . '\'); return false;">' . $button_text . '</a>';
}
add_shortcode('red_button', 'red_button_shortcode');
// Добавляем стили и скрипты
function add_button_styles_and_scripts() {
?>
<style>
.black-button,
.red-button {
display: inline-block;
width: 100%;
padding: 12px 20px;
text-align: center;
text-decoration: none;
border-radius: 5px;
font-weight: 500;
transition: background-color 0.3s;
cursor: pointer;
}
.black-button {
background-color: #000000;
color: #ffffff;
}
.red-button {
background-color: #FF0000;
color: #ffffff;
}
.black-button:hover {
background-color: #000000;
color: #ffffff;
text-decoration: none;
}
.red-button:hover {
background-color: #FF0000;
color: #ffffff;
text-decoration: none;
}
</style>
<script>
function addToCartAndRedirect(productId, checkoutUrl) {
// Добавляем загрузчик или блокируем кнопку
jQuery.ajax({
type: 'POST',
url: wc_add_to_cart_params.ajax_url,
data: {
'action': 'add_to_cart',
'product_id': productId,
'quantity': 1
},
success: function(response) {
// После успешного добавления в корзину перенаправляем на чекаут
window.location.href = checkoutUrl;
},
error: function(error) {
console.log(error);
alert('Error adding to cart');
}
});
}
</script>
<?php
}
add_action('wp_head', 'add_button_styles_and_scripts');
// Обработчик AJAX запроса для добавления в корзину
function ajax_add_to_cart() {
$product_id = isset($_POST['product_id']) ? intval($_POST['product_id']) : 0;
$quantity = isset($_POST['quantity']) ? intval($_POST['quantity']) : 1;
if ($product_id > 0) {
WC()->cart->empty_cart(); // Очищаем корзину перед добавлением нового товара
$added = WC()->cart->add_to_cart($product_id, $quantity);
if ($added) {
wp_send_json_success('Product added to cart');
} else {
wp_send_json_error('Failed to add product to cart');
}
} else {
wp_send_json_error('Invalid product ID');
}
wp_die();
}
add_action('wp_ajax_add_to_cart', 'ajax_add_to_cart');
add_action('wp_ajax_nopriv_add_to_cart', 'ajax_add_to_cart');
function get_same_category_products() {
global $post;
if (!is_product()) {
return '';
}
$product_cats = wp_get_post_terms($post->ID, 'product_cat');
if (empty($product_cats)) {
return '';
}
$primary_cat = $product_cats[0];
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'post__not_in' => array($post->ID),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $primary_cat->term_id,
),
),
'orderby' => 'rand'
);
$products = new WP_Query($args);
$output = '';
if ($products->have_posts()) {
$output .= '<div class="same-category-products">';
$output .= '<div class="products-carousel">';
while ($products->have_posts()) {
$products->the_post();
$output .= '<div class="carousel-item">';
$output .= do_shortcode('[elementor-template id="3125"]');
$output .= '</div>';
}
$output .= '</div>';
$output .= '<button class="carousel-prev">&#10094;</button>';
$output .= '<button class="carousel-next">&#10095;</button>';
$output .= '</div>';
}
wp_reset_postdata();
return $output;
}
function register_same_category_products_shortcode() {
add_shortcode('same_category_products', 'get_same_category_products');
}
add_action('init', 'register_same_category_products_shortcode');
function add_same_category_products_styles() {
?>
<style>
.same-category-products {
margin: 2em 0;
position: relative;
overflow: hidden;
padding-bottom: 20px;
}
.products-carousel {
display: flex;
transition: transform 0.3s ease-in-out;
min-height: 450px;
}
.carousel-item {
flex: 0 0 25%;
max-width: 25%;
padding: 0 10px;
box-sizing: border-box;
}
.carousel-prev,
.carousel-next {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: #000000;
color: white;
border: none;
padding: 10px 15px;
cursor: pointer;
z-index: 2;
}
.carousel-prev {
left: 0;
}
.carousel-next {
right: 0;
}
.carousel-prev:hover,
.carousel-next:hover {
background: #000000;
color: white;
}
/* Mobile styles */
@media screen and (max-width: 767px) {
.carousel-item {
flex: 0 0 50%;
max-width: 50%;
padding: 0 5px; /* Уменьшенные отступы для мобильной версии */
}
.products-carousel {
min-height: 350px;
}
.same-category-products {
padding: 0 15px; /* Добавляем отступы по бокам */
}
.carousel-prev,
.carousel-next {
padding: 8px 12px; /* Уменьшаем размер кнопок */
font-size: 14px; /* Уменьшаем размер стрелок */
}
.carousel-prev {
left: 5px; /* Приближаем кнопки к краю */
}
.carousel-next {
right: 5px;
}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const carousel = document.querySelector('.products-carousel');
const prevBtn = document.querySelector('.carousel-prev');
const nextBtn = document.querySelector('.carousel-next');
let position = 0;
function updateCarousel() {
const isMobile = window.innerWidth <= 767;
const itemsPerView = isMobile ? 2 : 4;
const itemWidth = 100 / itemsPerView;
const totalItems = carousel.children.length;
const maxPosition = Math.max(0, totalItems - itemsPerView);
carousel.style.transform = `translateX(-${position * itemWidth}%)`;
// Update position if needed when switching between mobile and desktop
position = Math.min(position, maxPosition);
}
prevBtn.addEventListener('click', () => {
position = Math.max(0, position - 1);
updateCarousel();
});
nextBtn.addEventListener('click', () => {
const isMobile = window.innerWidth <= 767;
const itemsPerView = isMobile ? 2 : 4;
const totalItems = carousel.children.length;
const maxPosition = Math.max(0, totalItems - itemsPerView);
position = Math.min(maxPosition, position + 1);
updateCarousel();
});
// Handle window resize
window.addEventListener('resize', updateCarousel);
// Initial update
updateCarousel();
});
</script>
<?php
}
add_action('wp_head', 'add_same_category_products_styles');
// Шорткод для отображения размеров продукта на грузинском языке
add_shortcode('product_dimensions_georgian', 'product_dimensions_georgian_shortcode');
// Добавляем стили для блока размеров на грузинском
add_action('wp_head', 'add_georgian_product_dimensions_styles');
function add_georgian_product_dimensions_styles() {
?>
<style>
.product-dimensions {
margin: 0;
font-size: 0.9em;
color: #333;
}
</style>
<?php
}
function product_dimensions_georgian_shortcode($atts) {
global $product;
// Если мы не на странице продукта, пытаемся получить ID из атрибутов
if (!is_a($product, 'WC_Product') && isset($atts['id'])) {
$product = wc_get_product($atts['id']);
}
// Если продукт не найден, возвращаем пустую строку
if (!is_a($product, 'WC_Product')) {
return '';
}
// Получаем размеры продукта
$weight = $product->get_weight();
$dimensions = $product->get_dimensions(false);
// Переводим единицы измерения на грузинский
$weight_unit = get_option('woocommerce_weight_unit');
$dimension_unit = get_option('woocommerce_dimension_unit');
// Замена единиц измерения на грузинские
$weight_unit_georgian = str_replace(
['kg', 'g', 'lbs', 'oz'],
['კგ', '', 'ფნტ', 'უნც'],
$weight_unit
);
$dimension_unit_georgian = str_replace(
['cm', 'm', 'mm', 'in', 'yd'],
['სმ', '', 'მმ', 'ინ', 'იარდ'],
$dimension_unit
);
// Формируем массив с параметрами
$dimensions_parts = array();
if (!empty($weight)) {
$dimensions_parts[] = "წონა: " . $weight . ' ' . $weight_unit_georgian;
}
if (!empty($dimensions['length'])) {
$dimensions_parts[] = "სიგრძე: " . $dimensions['length'] . ' ' . $dimension_unit_georgian;
}
if (!empty($dimensions['width'])) {
$dimensions_parts[] = "სიგანე: " . $dimensions['width'] . ' ' . $dimension_unit_georgian;
}
if (!empty($dimensions['height'])) {
$dimensions_parts[] = "სიმაღლე: " . $dimensions['height'] . ' ' . $dimension_unit_georgian;
}
// Если есть хотя бы один параметр, выводим блок
if (!empty($dimensions_parts)) {
return '<div class="product-dimensions"><strong>მიწოდება:</strong> <strong>' .
implode(' | ', $dimensions_parts) .
'</strong></div>';
}
return '';
}
// Шорткод для отображения размеров продукта на английском языке
add_shortcode('product_dimensions_english', 'product_dimensions_english_shortcode');
// Добавляем стили для блока размеров на английском
add_action('wp_head', 'add_english_product_dimensions_styles');
function add_english_product_dimensions_styles() {
?>
<style>
.product-dimensions {
margin: 0;
font-size: 0.9em;
color: #333;
}
</style>
<?php
}
function product_dimensions_english_shortcode($atts) {
global $product;
// Если мы не на странице продукта, пытаемся получить ID из атрибутов
if (!is_a($product, 'WC_Product') && isset($atts['id'])) {
$product = wc_get_product($atts['id']);
}
// Если продукт не найден, возвращаем пустую строку
if (!is_a($product, 'WC_Product')) {
return '';
}
// Получаем размеры продукта
$weight = $product->get_weight();
$dimensions = $product->get_dimensions(false);
// Формируем массив с параметрами
$dimensions_parts = array();
if (!empty($weight)) {
$dimensions_parts[] = "Weight: " . $weight . ' ' . get_option('woocommerce_weight_unit');
}
if (!empty($dimensions['length'])) {
$dimensions_parts[] = "Length: " . $dimensions['length'] . ' ' . get_option('woocommerce_dimension_unit');
}
if (!empty($dimensions['width'])) {
$dimensions_parts[] = "Width: " . $dimensions['width'] . ' ' . get_option('woocommerce_dimension_unit');
}
if (!empty($dimensions['height'])) {
$dimensions_parts[] = "Height: " . $dimensions['height'] . ' ' . get_option('woocommerce_dimension_unit');
}
// Если есть хотя бы один параметр, выводим блок
if (!empty($dimensions_parts)) {
return '<div class="product-dimensions"><strong>Delivery:</strong> <strong>' .
implode(' | ', $dimensions_parts) .
'</strong></div>';
}
return '';
}
// Функция для вывода перекрестных продаж с помощью шорткода
function custom_cross_sells_shortcode() {
ob_start(); // Начинаем буферизацию вывода
global $product;
// Проверяем, определен ли объект товара
if (!is_a($product, 'WC_Product')) {
return '';
}
// Получаем ID перекрестных продаж
$cross_sell_ids = $product->get_cross_sell_ids();
if (empty($cross_sell_ids)) {
return '';
}
// Заголовок секции
echo '<div class="ertad-qidva-section">';
echo '<h3 class="ertad-qidva-title">ერთად ყიდვა</h3>';
// Получаем объекты товаров
$cross_sell_products = array_map('wc_get_product', $cross_sell_ids);
echo '<div class="ertad-qidva-products">';
// Выводим основной товар
echo '<div class="ertad-qidva-main-product">';
echo '<div class="product-image"><a href="' . esc_url(get_permalink($product->get_id())) . '">' . $product->get_image('thumbnail') . '</a></div>';
echo '<div class="product-info">';
echo '<div class="product-title"><a href="' . esc_url(get_permalink($product->get_id())) . '">' . $product->get_name() . '</a></div>';
echo '<div class="product-price">' . $product->get_price_html() . '</div>';
echo '</div>';
echo '</div>';
// Выводим знак плюса только если есть перекрестные продажи
if (!empty($cross_sell_products)) {
echo '<div class="ertad-qidva-plus">+</div>';
}
// Выводим перекрестные продажи
foreach ($cross_sell_products as $cross_sell_product) {
if (!is_a($cross_sell_product, 'WC_Product') || !$cross_sell_product->is_in_stock()) {
continue;
}
$product_permalink = get_permalink($cross_sell_product->get_id());
echo '<div class="ertad-qidva-item" data-product-id="' . esc_attr($cross_sell_product->get_id()) . '">';
echo '<div class="product-image"><a href="' . esc_url($product_permalink) . '">' . $cross_sell_product->get_image('thumbnail') . '</a></div>';
echo '<div class="product-info">';
echo '<div class="product-title"><a href="' . esc_url($product_permalink) . '">' . $cross_sell_product->get_name() . '</a></div>';
echo '<div class="product-price">' . $cross_sell_product->get_price_html() . '</div>';
echo '</div>';
echo '<div class="product-remove"><span class="remove-cross-sell" data-product-id="' . esc_attr($cross_sell_product->get_id()) . '">×</span></div>';
echo '</div>';
if (next($cross_sell_products)) {
echo '<div class="ertad-qidva-plus">+</div>';
}
}
echo '</div>';
// Итоговая секция и кнопка добавления в корзину
echo '<div class="ertad-qidva-summary">';
echo '<div class="ertad-qidva-total">';
echo '<div class="total-label">ჯამში:</div>';
echo '<div class="total-price" id="ertad-qidva-total-price">' . wc_price($product->get_price()) . '</div>';
echo '</div>';
echo '<button type="button" class="button ertad-qidva-add-to-cart">ყიდვა</button>';
echo '</div>';
echo '</div>';
// JavaScript для обработки выбора товаров и обновления цены
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
// Хранение выбранных товаров
var selectedProducts = {};
var mainProductPrice = <?php echo (float)$product->get_price(); ?>;
// Инициализация выбранных товаров
<?php foreach ($cross_sell_products as $cross_sell_product):
if (!is_a($cross_sell_product, 'WC_Product') || !$cross_sell_product->is_in_stock()) continue; ?>
selectedProducts[<?php echo $cross_sell_product->get_id(); ?>] = {
id: <?php echo $cross_sell_product->get_id(); ?>,
price: <?php echo (float)$cross_sell_product->get_price(); ?>,
selected: true
};
<?php endforeach; ?>
// Обновление общей суммы
function updateTotalPrice() {
var totalPrice = mainProductPrice;
// Добавляем цены выбранных товаров
$.each(selectedProducts, function(id, product) {
if (product.selected) {
totalPrice += product.price;
}
});
$('#ertad-qidva-total-price').html('<?php echo get_woocommerce_currency_symbol(); ?>' + totalPrice.toFixed(2));
}
// Обработка удаления товара
$('.remove-cross-sell').click(function(e) {
e.preventDefault(); // Предотвращаем переход по ссылке при клике на крестик
e.stopPropagation(); // Останавливаем всплытие события
var productId = $(this).data('product-id');
var item = $(this).closest('.ertad-qidva-item');
var plus = item.next('.ertad-qidva-plus');
if (plus.length === 0) {
plus = item.prev('.ertad-qidva-plus');
}
// Удаляем товар и знак плюса из интерфейса
item.remove();
plus.remove();
// Помечаем товар как неактивный
if (selectedProducts[productId]) {
selectedProducts[productId].selected = false;
}
// Проверяем, остались ли выбранные товары
var anySelected = false;
$.each(selectedProducts, function(id, product) {
if (product.selected) {
anySelected = true;
return false; // Прерываем цикл $.each
}
});
// Если не осталось выбранных товаров, удаляем знак плюса после основного товара
if (!anySelected) {
$('.ertad-qidva-main-product').next('.ertad-qidva-plus').remove();
}
updateTotalPrice();
});
// Добавление всех выбранных товаров в корзину и переход на чекаут
$('.ertad-qidva-add-to-cart').click(function(e) {
e.preventDefault();
var products = [];
var $button = $(this);
// Добавляем индикатор загрузки
$button.addClass('loading').prop('disabled', true);
$button.html('<span class="loading-spinner"></span> ყიდვა');
// Добавляем основной товар
products.push({
product_id: <?php echo $product->get_id(); ?>,
quantity: 1
});
// Добавляем выбранные перекрестные продажи
$.each(selectedProducts, function(id, product) {
if (product.selected) {
products.push({
product_id: product.id,
quantity: 1
});
}
});
// Очищаем корзину перед добавлением
$.ajax({
type: 'POST',
url: wc_add_to_cart_params.ajax_url,
data: {
action: 'woocommerce_clear_cart_ajax',
security: '<?php echo wp_create_nonce('clear-cart'); ?>'
},
success: function() {
// После очистки корзины, добавляем товары
addProducts(0);
},
error: function() {
// Обработка ошибки
$button.removeClass('loading').prop('disabled', false);
$button.html('ყიდვა');
alert('Ошибка при очистке корзины.');
}
});
// Поочередно добавляем товары в корзину
function addProducts(index) {
if (index >= products.length) {
// Все товары добавлены, перенаправляем на страницу оформления заказа
window.location.href = '<?php echo wc_get_checkout_url(); ?>';
return;
}
var product = products[index];
$.ajax({
type: 'POST',
url: wc_add_to_cart_params.ajax_url,
data: {
action: 'woocommerce_ajax_add_to_cart',
product_id: product.product_id,
quantity: product.quantity,
security: '<?php echo wp_create_nonce('add-to-cart'); ?>'
},
success: function(response) {
if (response.error) {
$button.removeClass('loading').prop('disabled', false);
$button.html('ყიდვა');
alert('Ошибка при добавлении товара в корзину.');
return;
}
addProducts(index + 1);
},
error: function() {
$button.removeClass('loading').prop('disabled', false);
$button.html('ყიდვა');
alert('Ошибка при добавлении товара в корзину.');
}
});
}
});
// Инициализация цены
updateTotalPrice();
});
</script>
<?php
// Добавляем CSS для стилизации
?>
<style type="text/css">
.ertad-qidva-section {
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 20px;
margin: 30px 0;
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}
.ertad-qidva-title {
font-size: 20px;
margin-bottom: 20px;
font-weight: 600;
color: #333;
}
.ertad-qidva-products {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 10px;
}
.ertad-qidva-main-product,
.ertad-qidva-item {
display: flex;
align-items: center;
padding: 15px;
border: 1px solid #f0f0f0;
border-radius: 5px;
position: relative;
width: 100%;
max-width: 350px;
transition: all 0.3s ease;
}
.ertad-qidva-main-product {
background-color: #f9f9f9;
}
.ertad-qidva-item:hover {
border-color: #ddd;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.product-remove {
margin-left: 10px;
cursor: pointer;
}
.remove-cross-sell {
display: inline-block;
width: 22px;
height: 22px;
line-height: 20px;
text-align: center;
border-radius: 50%;
background-color: #f0f0f0;
color: #666;
font-size: 16px;
font-weight: bold;
transition: all 0.2s ease;
}
.remove-cross-sell:hover {
background-color: #e84c3d;
color: white;
}
.product-image {
width: 70px;
height: 70px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
}
.product-image img {
width: 100%;
height: auto;
max-height: 70px;
object-fit: contain;
display: block;
}
.product-info {
margin-left: 15px;
flex-grow: 1;
overflow: hidden;
}
.product-title {
font-weight: bold;
margin-bottom: 8px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.product-title a {
color: inherit;
text-decoration: none;
}
.product-title a:hover {
text-decoration: underline;
color: #e84c3d;
}
.ertad-qidva-plus {
font-size: 22px;
font-weight: bold;
color: #999;
padding: 0 5px;
}
.ertad-qidva-summary {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 25px;
padding-top: 20px;
border-top: 1px solid #e0e0e0;
}
.ertad-qidva-total {
display: flex;
align-items: center;
}
.total-label {
font-weight: bold;
margin-right: 10px;
font-size: 16px;
}
.total-price {
font-size: 20px;
font-weight: bold;
color: #e84c3d;
}
.ertad-qidva-add-to-cart {
background-color: #e84c3d;
color: white;
border: none;
padding: 12px 25px;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
transition: background-color 0.3s ease;
}
.ertad-qidva-add-to-cart:hover {
background-color: #d43c2d;
}
.ertad-qidva-add-to-cart.loading {
opacity: 0.8;
cursor: wait;
}
.loading-spinner {
display: inline-block;
width: 14px;
height: 14px;
border: 2px solid rgba(255,255,255,0.3);
border-radius: 50%;
border-top-color: #fff;
animation: spin 1s ease-in-out infinite;
margin-right: 5px;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
@media (max-width: 768px) {
.ertad-qidva-products {
flex-direction: column;
align-items: stretch;
}
.ertad-qidva-main-product,
.ertad-qidva-item {
max-width: 100%;
}
.ertad-qidva-plus {
align-self: center;
margin: 5px 0;
}
.ertad-qidva-summary {
flex-direction: column;
gap: 15px;
}
.ertad-qidva-add-to-cart {
width: 100%;
}
}
</style>
<?php
$output = ob_get_clean(); // Получаем содержимое буфера и очищаем его
return $output;
}
// Регистрируем шорткод [ertad_qidva]
add_shortcode('ertad_qidva', 'custom_cross_sells_shortcode');
// Функция для AJAX добавления товаров в корзину
add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'custom_ajax_add_to_cart');
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'custom_ajax_add_to_cart');
function custom_ajax_add_to_cart() {
check_ajax_referer('add-to-cart', 'security');
$product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
$quantity = empty($_POST['quantity']) ? 1 : wc_stock_amount($_POST['quantity']);
$passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity)) {
do_action('woocommerce_ajax_added_to_cart', $product_id);
if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
wc_add_to_cart_message(array($product_id => $quantity), true);
}
WC_AJAX::get_refreshed_fragments();
} else {
$data = array(
'error' => true,
'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id)
);
wp_send_json($data);
}
wp_die();
}
// Функция для очистки корзины через AJAX
add_action('wp_ajax_woocommerce_clear_cart_ajax', 'custom_clear_cart_ajax');
add_action('wp_ajax_nopriv_woocommerce_clear_cart_ajax', 'custom_clear_cart_ajax');
function custom_clear_cart_ajax() {
check_ajax_referer('clear-cart', 'security');
WC()->cart->empty_cart();
wp_send_json_success();
wp_die();
}
// WooCommerce AJAX Add to Cart კლასი და data-product_id დამატება Elementor-ის გენერირებულ ბმულებზე
add_filter( 'elementor/frontend/the_content', function( $content ) {
return preg_replace_callback(
'/<a([^>]+href=["\'][^"\']*add-to-cart=(\d+)[^>]*)>/i',
function( $matches ) {
$tag = $matches[0];
$product_id = (int) $matches[2];
// class დამატება
if ( strpos( $tag, 'ajax_add_to_cart' ) === false ) {
if ( preg_match('/class=["\']([^"\']*)["\']/', $tag) ) {
$tag = preg_replace(
'/class=["\']([^"\']*)["\']/',
'class="$1 add_to_cart_button ajax_add_to_cart"',
$tag
);
} else {
$tag = str_replace('<a ', '<a class="add_to_cart_button ajax_add_to_cart" ', $tag);
}
}
// data-product_id დამატება
if ( strpos( $tag, 'data-product_id' ) === false ) {
$tag = str_replace('<a ', '<a data-product_id="' . esc_attr( $product_id ) . '" ', $tag);
}
return $tag;
},
$content
);
}, 20 );
// გადამისამართების გათიშვა
add_filter( 'woocommerce_add_to_cart_redirect', '__return_false' );
// WooCommerce-ის საჭირო JS-ის ჩატვირთვა
add_action( 'wp_enqueue_scripts', function() {
wp_enqueue_script( 'wc-add-to-cart' );
wp_enqueue_script( 'wc-cart-fragments' );
}, 20 );
/* ენების შემცვლელი კოდი /
*/
if (!defined('ABSPATH')) exit;
/**
* Shortcode: [custom_lang_switcher]
* Minimal, JS/HTML/CSS-based language switcher with a flag and toggle.
*/
add_shortcode('custom_lang_switcher', function () {
ob_start(); ?>
<div class="lsw" data-current="" data-ka-url="" data-en-url=""></div>
<style>
.lsw { display: inline-block; }
/* 1px-ით ნაკლები დაშორება დროშასა და ღილაკს შორის */
.lsw-wrap {
display: inline-flex;
align-items: center;
gap: 6px;
}
.lsw-flag { width: 26px; height: auto; display: block; }
.lsw-toggle {
position: relative;
width: 56px;
height: 30px;
padding: 0;
border: 0;
background: transparent;
cursor: pointer;
outline: none;
border-radius: 999px; /* აქედანვე დავამრგვალეთ კონტეინერი */
}
/* ჰოვერზე იგივე ყვითელი, outline/box-shadow უცვლელი */
.lsw-toggle:hover .lsw-track {
background: #FFBD14 !important;
box-shadow: inset 0 0 0 2px rgba(0,0,0,.6);
}
/* ფოკუსზე მხოლოდ შიდა outline */
.lsw-toggle:focus-visible {
outline: none;
box-shadow: 0 0 0 2px #111 inset;
border-radius: 999px;
}
.lsw-track {
position: absolute;
inset: 0;
background: #FFBD14;
border-radius: 999px;
box-shadow: inset 0 0 0 2px rgba(0,0,0,.6);
}
.lsw-thumb {
position: absolute;
top: 4px;
left: 4px;
width: 22px;
height: 22px;
background: #111;
border-radius: 50%;
transition: left .25s ease;
}
.lsw-wrap.is-en .lsw-thumb { left: 30px; }
@media (max-width: 420px){
.lsw-flag { width: 22px; }
.lsw-toggle { width: 50px; height: 22px; }
.lsw-thumb { width: 14px; height: 14px; top: 4px; left: 4px; }
.lsw-wrap.is-en .lsw-thumb { left: 26px; }
.lsw-wrap {
gap: 2px !important; /* მობილურზე კიდევ უფრო ახლოს */
}
}
</style>
<script>
(function () {
const CONFIG = {
flags: {
ka: 'https://upload.wikimedia.org/wikipedia/commons/0/0f/Flag_of_Georgia.svg',
en: 'https://upload.wikimedia.org/wikipedia/commons/8/83/Flag_of_the_United_Kingdom_%283-5%29.svg'
},
homes: {
ka: '/',
en: '/en/'
},
pairs: [
['/', '/en/'],
['/კონტაქტი/', '/en/contact/'],
['/ენა-შეცვლა/', '/en/change-language/']
],
inferLanguage: () => {
const htmlLang = (document.documentElement.lang || '').toLowerCase();
if (htmlLang.startsWith('ka')) return 'ka';
if (htmlLang.startsWith('en')) return 'en';
const p = location.pathname.toLowerCase();
if (p === '/en' || p.startsWith('/en/')) return 'en';
return 'ka';
}
};
function normalizePath(p) {
try {
const u = new URL(p, location.origin);
let path = u.pathname;
if (!path.endsWith('/')) path += '/';
return path.toLowerCase();
} catch {
let path = p || '/';
if (!path.startsWith('/')) path = '/' + path;
if (!path.endsWith('/')) path += '/';
return path.toLowerCase();
}
}
function buildMap(pairs) {
const map = new Map();
pairs.forEach(([ka, en]) => {
const KA = normalizePath(ka);
const EN = normalizePath(en);
map.set(KA, EN);
map.set(EN, KA);
});
return map;
}
function resolveTarget(currentLang, map) {
const here = normalizePath(location.pathname);
if (map.has(here)) return map.get(here);
return currentLang === 'ka' ? CONFIG.homes.en : CONFIG.homes.ka;
}
function render(container, currentLang, targetUrl) {
const wrap = document.createElement('div');
wrap.className = 'lsw-wrap ' + (currentLang === 'en' ? 'is-en' : 'is-ka');
wrap.setAttribute('role', 'group');
wrap.setAttribute('aria-label', 'Language switcher');
const flag = document.createElement('img');
flag.className = 'lsw-flag';
flag.alt = currentLang === 'en' ? 'English' : 'ქართული';
flag.src = CONFIG.flags[currentLang];
flag.referrerPolicy = 'no-referrer';
flag.decoding = 'async';
flag.loading = 'lazy';
flag.onerror = function(){ this.style.display='none'; };
const btn = document.createElement('button');
btn.className = 'lsw-toggle';
btn.type = 'button';
btn.setAttribute('role', 'switch');
btn.setAttribute('aria-checked', currentLang === 'en' ? 'true' : 'false');
btn.setAttribute('aria-label', 'Switch language');
const track = document.createElement('span');
track.className = 'lsw-track';
const thumb = document.createElement('span');
thumb.className = 'lsw-thumb';
btn.appendChild(track);
btn.appendChild(thumb);
btn.addEventListener('click', function (e) {
e.preventDefault();
const url = targetUrl.startsWith('http') ? targetUrl : (location.origin + targetUrl);
window.location.href = url;
});
wrap.appendChild(flag);
wrap.appendChild(btn);
container.innerHTML = '';
container.appendChild(wrap);
}
function initOne(container, map) {
const dataKa = (container.getAttribute('data-ka-url') || '').trim();
const dataEn = (container.getAttribute('data-en-url') || '').trim();
let current = (container.getAttribute('data-current') || '').toLowerCase();
if (current !== 'ka' && current !== 'en') current = CONFIG.inferLanguage();
let target = '';
if (dataKa && dataEn) {
target = current === 'ka' ? dataEn : dataKa;
} else {
target = resolveTarget(current, map);
}
render(container, current, target);
}
function init() {
const map = buildMap(CONFIG.pairs);
document.querySelectorAll('.lsw').forEach(el => initOne(el, map));
}
if (document.readyState !== 'loading') init();
else document.addEventListener('DOMContentLoaded', init);
})();
</script>
<?php
return ob_get_clean();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment