Created
August 21, 2025 10:44
-
-
Save JusTruetice/579c34a5ef52b1695cc4445412e1a47d to your computer and use it in GitHub Desktop.
Wordpress old version function.php main
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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">❮</button>'; | |
| $output .= '<button class="carousel-next">❯</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