Files
dostavka_vodi/wp-content/themes/twentytwentyfour/functions.php
2026-04-18 19:05:33 +03:00

1348 lines
46 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Twenty Twenty-Four functions and definitions
*
* @link https://developer.wordpress.org/themes/basics/theme-functions/
*
* @package Twenty Twenty-Four
* @since Twenty Twenty-Four 1.0
*/
/**
* Register block styles.
*/
if ( ! function_exists( 'twentytwentyfour_block_styles' ) ) :
/**
* Registers custom block styles.
*
* @since Twenty Twenty-Four 1.0
* @return void
*/
function twentytwentyfour_block_styles() {
register_block_style(
'core/details',
array(
'name' => 'arrow-icon-details',
'label' => __( 'Arrow icon', 'twentytwentyfour' ),
/*
* Styles for the custom Arrow icon style of the Details block
*/
'inline_style' => '
.is-style-arrow-icon-details {
padding-top: var(--wp--preset--spacing--10);
padding-bottom: var(--wp--preset--spacing--10);
}
.is-style-arrow-icon-details summary {
list-style-type: "\2193\00a0\00a0\00a0";
}
.is-style-arrow-icon-details[open]>summary {
list-style-type: "\2192\00a0\00a0\00a0";
}',
)
);
register_block_style(
'core/post-terms',
array(
'name' => 'pill',
'label' => __( 'Pill', 'twentytwentyfour' ),
/*
* Styles variation for post terms
* https://github.com/WordPress/gutenberg/issues/24956
*/
'inline_style' => '
.is-style-pill a,
.is-style-pill span:not([class], [data-rich-text-placeholder]) {
display: inline-block;
background-color: var(--wp--preset--color--base-2);
padding: 0.375rem 0.875rem;
border-radius: var(--wp--preset--spacing--20);
}
.is-style-pill a:hover {
background-color: var(--wp--preset--color--contrast-3);
}',
)
);
register_block_style(
'core/list',
array(
'name' => 'checkmark-list',
'label' => __( 'Checkmark', 'twentytwentyfour' ),
/*
* Styles for the custom checkmark list block style
* https://github.com/WordPress/gutenberg/issues/51480
*/
'inline_style' => '
ul.is-style-checkmark-list {
list-style-type: "\2713";
}
ul.is-style-checkmark-list li {
padding-inline-start: 1ch;
}',
)
);
register_block_style(
'core/navigation-link',
array(
'name' => 'arrow-link',
'label' => __( 'With arrow', 'twentytwentyfour' ),
/*
* Styles for the custom arrow nav link block style
*/
'inline_style' => '
.is-style-arrow-link .wp-block-navigation-item__label:after {
content: "\2197";
padding-inline-start: 0.25rem;
vertical-align: middle;
text-decoration: none;
display: inline-block;
}',
)
);
register_block_style(
'core/heading',
array(
'name' => 'asterisk',
'label' => __( 'With asterisk', 'twentytwentyfour' ),
'inline_style' => "
.is-style-asterisk:before {
content: '';
width: 1.5rem;
height: 3rem;
background: var(--wp--preset--color--contrast-2, currentColor);
clip-path: path('M11.93.684v8.039l5.633-5.633 1.216 1.23-5.66 5.66h8.04v1.737H13.2l5.701 5.701-1.23 1.23-5.742-5.742V21h-1.737v-8.094l-5.77 5.77-1.23-1.217 5.743-5.742H.842V9.98h8.162l-5.701-5.7 1.23-1.231 5.66 5.66V.684h1.737Z');
display: block;
}
/* Hide the asterisk if the heading has no content, to avoid using empty headings to display the asterisk only, which is an A11Y issue */
.is-style-asterisk:empty:before {
content: none;
}
.is-style-asterisk:-moz-only-whitespace:before {
content: none;
}
.is-style-asterisk.has-text-align-center:before {
margin: 0 auto;
}
.is-style-asterisk.has-text-align-right:before {
margin-left: auto;
}
.rtl .is-style-asterisk.has-text-align-left:before {
margin-right: auto;
}",
)
);
}
endif;
add_action( 'init', 'twentytwentyfour_block_styles' );
/**
* Enable base theme supports used by SEO integrations.
*
* @return void
*/
function twentytwentyfour_theme_setup() {
add_theme_support( 'title-tag' );
}
add_action( 'after_setup_theme', 'twentytwentyfour_theme_setup' );
/**
* Enqueue block stylesheets.
*/
if ( ! function_exists( 'twentytwentyfour_block_stylesheets' ) ) :
/**
* Enqueues custom block stylesheets.
*
* @since Twenty Twenty-Four 1.0
* @return void
*/
function twentytwentyfour_block_stylesheets() {
/**
* The wp_enqueue_block_style() function allows us to enqueue a stylesheet
* for a specific block. These will only get loaded when the block is rendered
* (both in the editor and on the front end), improving performance
* and reducing the amount of data requested by visitors.
*
* See https://make.wordpress.org/core/2021/12/15/using-multiple-stylesheets-per-block/ for more info.
*/
wp_enqueue_block_style(
'core/button',
array(
'handle' => 'twentytwentyfour-button-style-outline',
'src' => get_parent_theme_file_uri( 'assets/css/button-outline.css' ),
'ver' => wp_get_theme( get_template() )->get( 'Version' ),
'path' => get_parent_theme_file_path( 'assets/css/button-outline.css' ),
)
);
}
endif;
add_action( 'init', 'twentytwentyfour_block_stylesheets' );
/**
* Register pattern categories.
*/
if ( ! function_exists( 'twentytwentyfour_pattern_categories' ) ) :
/**
* Registers pattern categories.
*
* @since Twenty Twenty-Four 1.0
* @return void
*/
function twentytwentyfour_pattern_categories() {
register_block_pattern_category(
'twentytwentyfour_page',
array(
'label' => _x( 'Pages', 'Block pattern category', 'twentytwentyfour' ),
'description' => __( 'A collection of full page layouts.', 'twentytwentyfour' ),
)
);
}
endif;
add_action( 'init', 'twentytwentyfour_pattern_categories' );
/**
* Use a standalone PHP template for the page slug "test1".
*
* @since Twenty Twenty-Four 1.0
*
* @param string $template Resolved template path.
* @return string
*/
function twentytwentyfour_test1_template( $template ) {
if ( ! is_front_page() && ! is_page( 'test1' ) ) {
return $template;
}
$custom_template = get_theme_file_path( 'page-test1.php' );
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
return $template;
}
add_filter( 'template_include', 'twentytwentyfour_test1_template' );
/**
* Use a standalone PHP template for the page slug "faq".
*
* @since Twenty Twenty-Four 1.0
*
* @param string $template Resolved template path.
* @return string
*/
function twentytwentyfour_faq_template( $template ) {
if ( ! is_page( 'faq' ) ) {
return $template;
}
$custom_template = get_theme_file_path( 'page-faq.php' );
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
return $template;
}
add_filter( 'template_include', 'twentytwentyfour_faq_template' );
/**
* Use a standalone PHP template for the page slug "contacts".
*
* @since Twenty Twenty-Four 1.0
*
* @param string $template Resolved template path.
* @return string
*/
function twentytwentyfour_contacts_template( $template ) {
if ( ! is_page( 'contacts' ) ) {
return $template;
}
$custom_template = get_theme_file_path( 'page-contacts.php' );
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
return $template;
}
add_filter( 'template_include', 'twentytwentyfour_contacts_template' );
/**
* Use a standalone PHP template for the page slug "delivery".
*
* @since Twenty Twenty-Four 1.0
*
* @param string $template Resolved template path.
* @return string
*/
function twentytwentyfour_delivery_template( $template ) {
if ( ! is_page( 'delivery' ) ) {
return $template;
}
$custom_template = get_theme_file_path( 'page-delivery.php' );
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
return $template;
}
add_filter( 'template_include', 'twentytwentyfour_delivery_template' );
/**
* Use a standalone PHP template for the page slug "service".
*
* @since Twenty Twenty-Four 1.0
*
* @param string $template Resolved template path.
* @return string
*/
function twentytwentyfour_service_template( $template ) {
if ( ! is_page( 'service' ) ) {
return $template;
}
$custom_template = get_theme_file_path( 'page-service.php' );
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
return $template;
}
add_filter( 'template_include', 'twentytwentyfour_service_template' );
/**
* Use a lightweight custom template for the WooCommerce checkout page.
*
* @since Twenty Twenty-Four 1.0
*
* @param string $template Resolved template path.
* @return string
*/
function twentytwentyfour_checkout_template( $template ) {
if ( ! function_exists( 'is_checkout' ) || ! is_checkout() || is_order_received_page() ) {
return $template;
}
$custom_template = get_theme_file_path( 'page-checkout.php' );
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
return $template;
}
add_filter( 'template_include', 'twentytwentyfour_checkout_template', 20 );
/**
* Use a lightweight custom template for the WooCommerce cart page.
*
* @since Twenty Twenty-Four 1.0
*
* @param string $template Resolved template path.
* @return string
*/
function twentytwentyfour_cart_template( $template ) {
if ( ! function_exists( 'is_cart' ) || ! is_cart() ) {
return $template;
}
$custom_template = get_theme_file_path( 'page-cart.php' );
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
return $template;
}
add_filter( 'template_include', 'twentytwentyfour_cart_template', 20 );
/**
* Use a lightweight custom template for the WooCommerce shop page.
*
* @since Twenty Twenty-Four 1.0
*
* @param string $template Resolved template path.
* @return string
*/
function twentytwentyfour_shop_template( $template ) {
if ( ! function_exists( 'is_shop' ) || ! is_shop() ) {
return $template;
}
$custom_template = get_theme_file_path( 'page-shop.php' );
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
return $template;
}
add_filter( 'template_include', 'twentytwentyfour_shop_template', 20 );
/**
* Force the custom blog index template for the posts page.
*
* @since Twenty Twenty-Four 1.0
*
* @param string $template Resolved template path.
* @return string
*/
function twentytwentyfour_blog_home_template( $template ) {
if ( ! is_home() ) {
return $template;
}
$custom_template = get_theme_file_path( 'home.php' );
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
return $template;
}
add_filter( 'template_include', 'twentytwentyfour_blog_home_template', 25 );
/**
* Force the custom single post template.
*
* @since Twenty Twenty-Four 1.0
*
* @param string $template Resolved template path.
* @return string
*/
function twentytwentyfour_single_post_template( $template ) {
if ( ! is_singular( 'post' ) ) {
return $template;
}
$custom_template = get_theme_file_path( 'single.php' );
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
return $template;
}
add_filter( 'template_include', 'twentytwentyfour_single_post_template', 25 );
/**
* Enqueue standalone landing assets for the page slug "test1".
*
* @since Twenty Twenty-Four 1.0
* @return void
*/
function twentytwentyfour_test1_assets() {
$use_test1_assets = is_front_page() || is_home() || is_singular( 'post' ) || is_page( array( 'test1', 'faq', 'contacts', 'delivery', 'service' ) );
if ( ! $use_test1_assets ) {
return;
}
$landing_css_file = get_theme_file_path( 'assets/css/test1-landing.css' );
$landing_js_file = get_theme_file_path( 'assets/js/test1-landing.js' );
if ( $use_test1_assets ) {
wp_dequeue_style( 'global-styles' );
wp_dequeue_style( 'wp-block-library' );
wp_dequeue_style( 'wp-block-library-theme' );
wp_dequeue_style( 'classic-theme-styles' );
}
wp_enqueue_style(
'twentytwentyfour-test1-fonts',
'https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;700;800&display=swap',
array(),
null
);
if ( file_exists( $landing_css_file ) ) {
wp_enqueue_style(
'twentytwentyfour-test1-style',
get_theme_file_uri( 'assets/css/test1-landing.css' ),
array( 'twentytwentyfour-test1-fonts' ),
(string) filemtime( $landing_css_file )
);
}
if ( ( is_front_page() || is_page( 'test1' ) ) && file_exists( $landing_js_file ) ) {
wp_enqueue_script(
'twentytwentyfour-test1-script',
get_theme_file_uri( 'assets/js/test1-landing.js' ),
array(),
(string) filemtime( $landing_js_file ),
true
);
wp_localize_script(
'twentytwentyfour-test1-script',
'test1LeadForm',
array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'action' => 'twentytwentyfour_submit_lead',
'nonce' => wp_create_nonce( 'twentytwentyfour_submit_lead' ),
)
);
if ( class_exists( 'WooCommerce' ) ) {
wp_localize_script(
'twentytwentyfour-test1-script',
'test1WooCommerce',
array(
'addToCartUrl' => WC_AJAX::get_endpoint( 'add_to_cart' ),
'cartUrl' => wc_get_cart_url(),
'checkoutUrl' => wc_get_checkout_url(),
)
);
}
}
if ( is_page( 'faq' ) ) {
$faq_js_file = get_theme_file_path( 'assets/js/test1-faq.js' );
if ( file_exists( $faq_js_file ) ) {
wp_enqueue_script(
'twentytwentyfour-test1-faq-script',
get_theme_file_uri( 'assets/js/test1-faq.js' ),
array(),
(string) filemtime( $faq_js_file ),
true
);
}
}
if ( is_page( 'contacts' ) ) {
$contacts_js_file = get_theme_file_path( 'assets/js/test1-contacts.js' );
if ( file_exists( $contacts_js_file ) ) {
wp_enqueue_script(
'twentytwentyfour-test1-contacts-script',
get_theme_file_uri( 'assets/js/test1-contacts.js' ),
array(),
(string) filemtime( $contacts_js_file ),
true
);
wp_localize_script(
'twentytwentyfour-test1-contacts-script',
'test1ContactsForm',
array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'action' => 'twentytwentyfour_submit_lead',
'nonce' => wp_create_nonce( 'twentytwentyfour_submit_lead' ),
)
);
}
}
}
add_action( 'wp_enqueue_scripts', 'twentytwentyfour_test1_assets', 100 );
/**
* Send a formatted message to Telegram.
*
* Configure credentials in wp-config.php:
* define( 'TWENTYTWENTYFOUR_TELEGRAM_BOT_TOKEN', '...' );
* define( 'TWENTYTWENTYFOUR_TELEGRAM_CHAT_ID', '...' );
*
* @param string $title Message title.
* @param array $fields Key-value pairs for message rows.
* @return bool
*/
function twentytwentyfour_send_telegram_message( $title, $fields ) {
$token = defined( 'TWENTYTWENTYFOUR_TELEGRAM_BOT_TOKEN' ) ? (string) constant( 'TWENTYTWENTYFOUR_TELEGRAM_BOT_TOKEN' ) : '';
$chat_id = defined( 'TWENTYTWENTYFOUR_TELEGRAM_CHAT_ID' ) ? (string) constant( 'TWENTYTWENTYFOUR_TELEGRAM_CHAT_ID' ) : '';
if ( '' === trim( $token ) || '' === trim( $chat_id ) ) {
return false;
}
$rows = array();
$rows[] = '<b>' . esc_html( wp_strip_all_tags( (string) $title ) ) . '</b>';
foreach ( $fields as $label => $value ) {
$clean_value = trim( wp_strip_all_tags( (string) $value ) );
if ( '' === $clean_value ) {
continue;
}
$rows[] = '<b>' . esc_html( wp_strip_all_tags( (string) $label ) ) . ':</b> ' . esc_html( $clean_value );
}
$response = wp_remote_post(
'https://api.telegram.org/bot' . rawurlencode( $token ) . '/sendMessage',
array(
'timeout' => 12,
'body' => array(
'chat_id' => $chat_id,
'parse_mode' => 'HTML',
'text' => implode( "\n", $rows ),
),
)
);
if ( is_wp_error( $response ) ) {
return false;
}
$status_code = (int) wp_remote_retrieve_response_code( $response );
return $status_code >= 200 && $status_code < 300;
}
/**
* Handle AJAX lead submissions from landing and contacts forms.
*
* @return void
*/
function twentytwentyfour_submit_lead_ajax() {
if ( ! check_ajax_referer( 'twentytwentyfour_submit_lead', 'nonce', false ) ) {
wp_send_json_error( array( 'message' => __( 'Ошибка проверки формы. Обновите страницу и попробуйте снова.', 'twentytwentyfour' ) ), 403 );
}
$form_type = isset( $_POST['form_type'] ) ? sanitize_key( wp_unslash( $_POST['form_type'] ) ) : 'contacts_page';
$page_url = isset( $_POST['page_url'] ) ? esc_url_raw( wp_unslash( $_POST['page_url'] ) ) : '';
if ( 'contacts' === $form_type ) {
$form_type = false !== strpos( $page_url, '/contacts' ) ? 'contacts_page' : 'landing_contacts';
}
if ( 'landing_order' === $form_type ) {
$name = isset( $_POST['customerName'] ) ? sanitize_text_field( wp_unslash( $_POST['customerName'] ) ) : '';
$phone = isset( $_POST['customerPhone'] ) ? sanitize_text_field( wp_unslash( $_POST['customerPhone'] ) ) : '';
$address = isset( $_POST['customerAddress'] ) ? sanitize_text_field( wp_unslash( $_POST['customerAddress'] ) ) : '';
$type = isset( $_POST['customerType'] ) ? sanitize_text_field( wp_unslash( $_POST['customerType'] ) ) : '';
$comment = isset( $_POST['customerOrder'] ) ? sanitize_textarea_field( wp_unslash( $_POST['customerOrder'] ) ) : '';
if ( '' === $name || '' === $phone ) {
wp_send_json_error( array( 'message' => __( 'Укажите имя и телефон.', 'twentytwentyfour' ) ), 422 );
}
$sent = twentytwentyfour_send_telegram_message(
'Новая заявка с главной страницы (модалка заказа)',
array(
'Имя' => $name,
'Телефон' => $phone,
'Адрес' => $address,
'Тип' => $type,
'Комментарий' => $comment,
'Источник' => 'Главная страница (модалка заказа)',
'URL' => $page_url,
)
);
} elseif ( 'landing_contacts' === $form_type ) {
$name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';
$phone = isset( $_POST['phone'] ) ? sanitize_text_field( wp_unslash( $_POST['phone'] ) ) : '';
$address = isset( $_POST['address'] ) ? sanitize_text_field( wp_unslash( $_POST['address'] ) ) : '';
$comment = isset( $_POST['comment'] ) ? sanitize_textarea_field( wp_unslash( $_POST['comment'] ) ) : '';
if ( '' === $name || '' === $phone ) {
wp_send_json_error( array( 'message' => __( 'Укажите имя и телефон.', 'twentytwentyfour' ) ), 422 );
}
$sent = twentytwentyfour_send_telegram_message(
'Новая заявка с главной страницы (контактная форма)',
array(
'Имя' => $name,
'Телефон' => $phone,
'Адрес' => $address,
'Комментарий' => $comment,
'Источник' => 'Главная страница (блок Контакты)',
'URL' => $page_url,
)
);
} else {
$name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';
$phone = isset( $_POST['phone'] ) ? sanitize_text_field( wp_unslash( $_POST['phone'] ) ) : '';
$address = isset( $_POST['address'] ) ? sanitize_text_field( wp_unslash( $_POST['address'] ) ) : '';
$comment = isset( $_POST['comment'] ) ? sanitize_textarea_field( wp_unslash( $_POST['comment'] ) ) : '';
if ( '' === $name || '' === $phone ) {
wp_send_json_error( array( 'message' => __( 'Укажите имя и телефон.', 'twentytwentyfour' ) ), 422 );
}
$sent = twentytwentyfour_send_telegram_message(
'Новая заявка со страницы Контакты',
array(
'Имя' => $name,
'Телефон' => $phone,
'Адрес' => $address,
'Комментарий' => $comment,
'Источник' => 'Страница Контакты',
'URL' => $page_url,
)
);
}
if ( ! $sent ) {
wp_send_json_error( array( 'message' => __( 'Не удалось отправить заявку. Проверьте настройки Telegram.', 'twentytwentyfour' ) ), 500 );
}
wp_send_json_success( array( 'message' => __( 'Спасибо! Заявка принята.', 'twentytwentyfour' ) ) );
}
add_action( 'wp_ajax_twentytwentyfour_submit_lead', 'twentytwentyfour_submit_lead_ajax' );
add_action( 'wp_ajax_nopriv_twentytwentyfour_submit_lead', 'twentytwentyfour_submit_lead_ajax' );
/**
* Send WooCommerce checkout orders to Telegram.
*
* @param int $order_id Order ID.
* @param array $posted_data Checkout payload.
* @param WC_Order $order Order object.
* @return void
*/
function twentytwentyfour_send_checkout_order_to_telegram( $order_id, $posted_data, $order ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$items = array();
foreach ( $order->get_items() as $item ) {
if ( ! $item instanceof WC_Order_Item_Product ) {
continue;
}
$items[] = sprintf( '%s x %d', $item->get_name(), (int) $item->get_quantity() );
}
$address_parts = array_filter(
array(
$order->get_billing_city(),
$order->get_billing_address_1(),
(string) get_post_meta( $order_id, '_billing_house', true ),
(string) get_post_meta( $order_id, '_billing_flat', true ),
(string) get_post_meta( $order_id, '_billing_entrance_floor', true ),
)
);
$fields = array(
'Заказ' => '#' . $order->get_order_number(),
'Имя' => $order->get_billing_first_name(),
'Телефон' => $order->get_billing_phone(),
'Адрес' => implode( ', ', $address_parts ),
'Когда доставить' => (string) get_post_meta( $order_id, '_tw_delivery_day', true ),
'Интервал' => (string) get_post_meta( $order_id, '_tw_delivery_time', true ),
'Обмен тары' => (string) get_post_meta( $order_id, '_tw_bottle_exchange', true ),
'Комментарий' => $order->get_customer_note(),
'Состав' => implode( '; ', $items ),
'Сумма' => wp_strip_all_tags( $order->get_formatted_order_total() ),
);
twentytwentyfour_send_telegram_message( 'Новый заказ с сайта', $fields );
}
add_action( 'woocommerce_checkout_order_processed', 'twentytwentyfour_send_checkout_order_to_telegram', 20, 3 );
/**
* Enqueue shared test1 header/footer styles for cart and checkout.
*
* @since Twenty Twenty-Four 1.0
* @return void
*/
function twentytwentyfour_test1_shared_shell_assets() {
if ( ! ( ( function_exists( 'is_checkout' ) && is_checkout() && ! is_order_received_page() ) || ( function_exists( 'is_cart' ) && is_cart() ) || ( function_exists( 'is_shop' ) && is_shop() ) || is_home() || is_singular( 'post' ) || is_page( 'faq' ) || is_page( 'contacts' ) || is_page( 'delivery' ) || is_page( 'service' ) ) ) {
return;
}
$shared_shell_css = get_theme_file_path( 'assets/css/test1-shared-shell.css' );
wp_enqueue_style(
'twentytwentyfour-test1-fonts',
'https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;700;800&display=swap',
array(),
null
);
if ( file_exists( $shared_shell_css ) ) {
wp_enqueue_style(
'twentytwentyfour-test1-shared-shell-style',
get_theme_file_uri( 'assets/css/test1-shared-shell.css' ),
array( 'twentytwentyfour-test1-fonts' ),
(string) filemtime( $shared_shell_css )
);
}
}
add_action( 'wp_enqueue_scripts', 'twentytwentyfour_test1_shared_shell_assets', 110 );
/**
* Free shipping threshold for custom notices.
*
* @return float
*/
function twentytwentyfour_water_delivery_free_shipping_threshold() {
return (float) apply_filters( 'twentytwentyfour_water_delivery_free_shipping_threshold', 1000 );
}
/**
* Bottle deposit fee when no exchange is selected.
*
* @return float
*/
function twentytwentyfour_water_delivery_deposit_fee() {
return (float) apply_filters( 'twentytwentyfour_water_delivery_deposit_fee', 250 );
}
/**
* Check whether a dedicated SEO plugin is active.
*
* @return bool
*/
function twentytwentyfour_has_seo_plugin() {
return defined( 'WPSEO_VERSION' ) || defined( 'RANK_MATH_VERSION' );
}
/**
* Resolve SEO source page id for custom and WooCommerce contexts.
*
* @return int
*/
function twentytwentyfour_seo_context_page_id() {
if ( is_admin() ) {
return 0;
}
if ( is_front_page() ) {
$test1_page = get_page_by_path( 'test1' );
if ( $test1_page instanceof WP_Post ) {
return (int) $test1_page->ID;
}
return (int) get_queried_object_id();
}
if ( is_page( array( 'test1', 'faq', 'contacts', 'delivery', 'service' ) ) ) {
return (int) get_queried_object_id();
}
if ( function_exists( 'is_cart' ) && is_cart() ) {
return (int) wc_get_page_id( 'cart' );
}
if ( function_exists( 'is_checkout' ) && is_checkout() && ! is_order_received_page() ) {
return (int) wc_get_page_id( 'checkout' );
}
if ( function_exists( 'is_shop' ) && is_shop() ) {
return (int) wc_get_page_id( 'shop' );
}
return 0;
}
/**
* Use Yoast SEO title from related page for custom templates.
*
* @param string $title Current Yoast title.
* @return string
*/
function twentytwentyfour_yoast_context_title( $title ) {
$page_id = twentytwentyfour_seo_context_page_id();
if ( $page_id <= 0 ) {
return $title;
}
$custom_title = (string) get_post_meta( $page_id, '_yoast_wpseo_title', true );
if ( '' === trim( $custom_title ) ) {
return $title;
}
$post = get_post( $page_id );
if ( function_exists( 'wpseo_replace_vars' ) && $post instanceof WP_Post ) {
$custom_title = wpseo_replace_vars( $custom_title, $post );
}
return wp_strip_all_tags( $custom_title );
}
add_filter( 'wpseo_title', 'twentytwentyfour_yoast_context_title', 20 );
/**
* Use Yoast SEO description from related page for custom templates.
*
* @param string $description Current Yoast description.
* @return string
*/
function twentytwentyfour_yoast_context_metadesc( $description ) {
$page_id = twentytwentyfour_seo_context_page_id();
if ( $page_id <= 0 ) {
return $description;
}
$custom_description = (string) get_post_meta( $page_id, '_yoast_wpseo_metadesc', true );
if ( '' === trim( $custom_description ) ) {
return $description;
}
$post = get_post( $page_id );
if ( function_exists( 'wpseo_replace_vars' ) && $post instanceof WP_Post ) {
$custom_description = wpseo_replace_vars( $custom_description, $post );
}
return wp_strip_all_tags( $custom_description );
}
add_filter( 'wpseo_metadesc', 'twentytwentyfour_yoast_context_metadesc', 20 );
/**
* Get long-form SEO text for cart and checkout pages.
*
* @param string $context Page context.
* @return string
*/
function twentytwentyfour_water_delivery_seo_copy( $context ) {
if ( 'checkout' === $context ) {
return 'Оформление заказа воды в Севастополе должно быть быстрым и понятным, особенно когда вода нужна домой или в офис без лишних звонков и долгих подтверждений. На этой странице вы можете за несколько минут завершить заказ воды 19 литров, питьевой и минеральной воды, указать удобный адрес и выбрать подходящий способ оплаты. Мы доставляем воду в Гагаринский район, Ленинский район, Нахимовский район, Балаклаву и другие части города, поэтому оформить доставку питьевой воды можно в удобном для вас формате. Если вам нужна вода на дом в Севастополе для семьи, кухни или кулера, просто проверьте состав заказа и заполните контакты. Для компаний и коммерческих объектов доступен заказ воды в офис с подтверждением интервала и возможностью безналичной оплаты. Такой сценарий помогает быстро заказать воду 19 литров с доставкой, избежать ошибок в адресе и сразу передать нам всю информацию по подъезду, этажу и таре. Мы стараемся сделать оформление заказа удобным, чтобы доставка воды Севастополь воспринималась как простой сервис на каждый день, а не как долгий процесс с лишними шагами.';
}
return 'Корзина на сайте доставки воды в Севастополе помогает быстро проверить состав заказа перед оформлением и убедиться, что в нем уже есть все нужные позиции: вода 19 литров, питьевая вода для кухни, минеральная вода для гостей, офиса или коммерческого помещения. Здесь можно изменить количество бутылей, удалить лишние товары и сразу увидеть итоговую сумму, стоимость доставки и дополнительные условия заказа. Такой формат особенно удобен для клиентов, которым нужна вода на дом в Севастополе без долгого оформления и повторных уточнений по телефону. Если вы заказываете доставку питьевой воды регулярно, корзина позволяет быстро собрать привычный набор и сразу перейти к следующему шагу. Мы доставляем заказы по Гагаринскому району, Ленинскому району, Нахимовскому району, Балаклаве и другим частям города, поэтому заказать воду 19 литров или дополнительные товары для кулера можно в одном месте. Перед оформлением вы можете проверить объем воды, количество бутылей и итоговую стоимость, а затем перейти на страницу подтверждения заказа. Такой подход делает доставку воды Севастополь удобной и понятной как для частных клиентов, так и для офисов, кафе, салонов и небольших компаний.';
}
/**
* Output progress indicator for cart and checkout pages.
*
* @param string $current Current step.
* @return void
*/
function twentytwentyfour_water_delivery_progress_markup( $current ) {
$steps = array(
'cart' => __( 'Корзина', 'twentytwentyfour' ),
'checkout' => __( 'Оформление', 'twentytwentyfour' ),
'done' => __( 'Готово', 'twentytwentyfour' ),
);
?>
<div class="checkout-progress" aria-label="<?php esc_attr_e( 'Прогресс оформления заказа', 'twentytwentyfour' ); ?>">
<?php foreach ( $steps as $step_key => $label ) : ?>
<?php
$classes = 'checkout-progress-step';
if ( $step_key === $current ) {
$classes .= ' is-active';
} elseif ( 'cart' === $current && 'done' !== $step_key ) {
$classes .= ' is-pending';
} elseif ( 'checkout' === $current && 'done' === $step_key ) {
$classes .= ' is-pending';
} else {
$classes .= ' is-complete';
}
?>
<span class="<?php echo esc_attr( $classes ); ?>"><span><?php echo esc_html( $label ); ?></span></span>
<?php endforeach; ?>
</div>
<?php
}
/**
* Add and reorder checkout fields for local delivery.
*
* @param array $fields Checkout fields.
* @return array
*/
function twentytwentyfour_water_delivery_checkout_fields( $fields ) {
unset( $fields['billing']['billing_company'], $fields['billing']['billing_postcode'] );
if ( isset( $fields['billing']['billing_city'] ) ) {
$fields['billing']['billing_city']['default'] = __( 'Севастополь', 'twentytwentyfour' );
$fields['billing']['billing_city']['required'] = true;
$fields['billing']['billing_city']['priority'] = 45;
$fields['billing']['billing_city']['custom_attributes'] = array( 'readonly' => 'readonly' );
$fields['billing']['billing_city']['label'] = __( 'Город', 'twentytwentyfour' );
$fields['billing']['billing_city']['class'] = array( 'form-row-first' );
}
if ( isset( $fields['billing']['billing_first_name'] ) ) {
$fields['billing']['billing_first_name']['priority'] = 10;
$fields['billing']['billing_first_name']['label'] = __( 'Имя', 'twentytwentyfour' );
}
if ( isset( $fields['billing']['billing_phone'] ) ) {
$fields['billing']['billing_phone']['priority'] = 20;
$fields['billing']['billing_phone']['required'] = true;
$fields['billing']['billing_phone']['label'] = __( 'Телефон', 'twentytwentyfour' );
$fields['billing']['billing_phone']['placeholder'] = '+7 (___) ___-__-__';
}
if ( isset( $fields['billing']['billing_address_1'] ) ) {
$fields['billing']['billing_address_1']['priority'] = 50;
$fields['billing']['billing_address_1']['label'] = __( 'Улица', 'twentytwentyfour' );
$fields['billing']['billing_address_1']['placeholder'] = __( 'Улица и район доставки', 'twentytwentyfour' );
$fields['billing']['billing_address_1']['class'] = array( 'form-row-wide', 'has-address-autofill' );
}
$fields['billing']['billing_house'] = array(
'label' => __( 'Дом', 'twentytwentyfour' ),
'required' => true,
'class' => array( 'form-row-first' ),
'priority' => 55,
);
$fields['billing']['billing_flat'] = array(
'label' => __( 'Квартира', 'twentytwentyfour' ),
'required' => false,
'class' => array( 'form-row-last' ),
'priority' => 56,
);
$fields['billing']['billing_entrance_floor'] = array(
'label' => __( 'Подъезд / этаж', 'twentytwentyfour' ),
'required' => false,
'class' => array( 'form-row-wide' ),
'priority' => 57,
);
$fields['order']['tw_delivery_day'] = array(
'type' => 'select',
'label' => __( 'Когда доставить', 'twentytwentyfour' ),
'required' => true,
'class' => array( 'form-row-first' ),
'priority' => 15,
'options' => array(
'' => __( 'Выберите день', 'twentytwentyfour' ),
'today' => __( 'Сегодня', 'twentytwentyfour' ),
'tomorrow' => __( 'Завтра', 'twentytwentyfour' ),
),
);
$fields['order']['tw_delivery_time'] = array(
'type' => 'select',
'label' => __( 'Интервал времени', 'twentytwentyfour' ),
'required' => true,
'class' => array( 'form-row-last' ),
'priority' => 16,
'options' => array(
'' => __( 'Выберите интервал', 'twentytwentyfour' ),
'08-12' => '08:00-12:00',
'12-16' => '12:00-16:00',
'16-20' => '16:00-20:00',
),
);
$fields['order']['tw_bottle_exchange'] = array(
'type' => 'select',
'label' => __( 'Возврат тары', 'twentytwentyfour' ),
'required' => true,
'class' => array( 'form-row-wide' ),
'priority' => 17,
'options' => array(
'exchange' => __( 'Есть обмен пустой тары', 'twentytwentyfour' ),
'no_exchange' => __( 'Нужна новая тара, добавить залог', 'twentytwentyfour' ),
),
);
if ( isset( $fields['order']['order_comments'] ) ) {
$fields['order']['order_comments']['priority'] = 20;
$fields['order']['order_comments']['label'] = __( 'Комментарий', 'twentytwentyfour' );
$fields['order']['order_comments']['placeholder'] = __( 'Комментарий к доставке, ориентир, код домофона', 'twentytwentyfour' );
}
return $fields;
}
/**
* Store bottle exchange choice in session during checkout refresh.
*
* @param string $posted_data Serialized checkout payload.
* @return void
*/
function twentytwentyfour_water_delivery_update_order_review( $posted_data ) {
parse_str( $posted_data, $data );
if ( isset( $data['tw_bottle_exchange'] ) && WC()->session ) {
WC()->session->set( 'tw_bottle_exchange', sanitize_text_field( wp_unslash( $data['tw_bottle_exchange'] ) ) );
}
}
/**
* Add deposit fee if there is no bottle exchange.
*
* @param WC_Cart $cart Cart object.
* @return void
*/
function twentytwentyfour_water_delivery_add_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
if ( ! $cart instanceof WC_Cart ) {
return;
}
$bottle_exchange = WC()->session ? WC()->session->get( 'tw_bottle_exchange', 'exchange' ) : 'exchange';
if ( 'no_exchange' === $bottle_exchange ) {
$cart->add_fee( __( 'Залог за тару', 'twentytwentyfour' ), twentytwentyfour_water_delivery_deposit_fee(), false );
}
}
/**
* Validate custom checkout data.
*
* @return void
*/
function twentytwentyfour_water_delivery_validate_checkout() {
if ( empty( $_POST['billing_phone'] ) ) {
return;
}
$phone_digits = preg_replace( '/\D+/', '', wp_unslash( $_POST['billing_phone'] ) );
if ( strlen( $phone_digits ) < 11 ) {
wc_add_notice( __( 'Укажите корректный телефон для подтверждения заказа.', 'twentytwentyfour' ), 'error' );
}
}
/**
* Save custom checkout fields to order meta.
*
* @param int $order_id Order ID.
* @return void
*/
function twentytwentyfour_water_delivery_save_checkout_meta( $order_id ) {
$fields = array(
'billing_house',
'billing_flat',
'billing_entrance_floor',
'tw_delivery_day',
'tw_delivery_time',
'tw_bottle_exchange',
);
foreach ( $fields as $field ) {
if ( isset( $_POST[ $field ] ) ) {
update_post_meta( $order_id, '_' . $field, sanitize_text_field( wp_unslash( $_POST[ $field ] ) ) );
}
}
}
/**
* Add cart helper panel before the cart table.
*
* @return void
*/
function twentytwentyfour_water_delivery_before_cart() {
$threshold = twentytwentyfour_water_delivery_free_shipping_threshold();
$subtotal = WC()->cart ? (float) WC()->cart->get_subtotal() : 0;
$remaining = max( 0, $threshold - $subtotal );
$account_url = function_exists( 'wc_get_account_endpoint_url' ) ? wc_get_account_endpoint_url( 'orders' ) : '';
?>
<div class="water-commerce-panel water-commerce-panel-cart js-cart-dynamic-region">
<div class="water-commerce-panel-head">
<h2><?php esc_html_e( 'Проверьте заказ перед оформлением', 'twentytwentyfour' ); ?></h2>
<p><?php esc_html_e( 'Измените количество бутылей, удалите лишние позиции и перейдите к оформлению доставки воды по Севастополю.', 'twentytwentyfour' ); ?></p>
</div>
<div class="water-commerce-benefits">
<span><?php esc_html_e( 'Доставка воды по Севастополю за 2-4 часа', 'twentytwentyfour' ); ?></span>
<span><?php esc_html_e( 'Работаем ежедневно', 'twentytwentyfour' ); ?></span>
<span><?php esc_html_e( 'Чистая сертифицированная вода', 'twentytwentyfour' ); ?></span>
</div>
<div class="water-commerce-alerts">
<?php if ( $remaining > 0 ) : ?>
<div class="water-commerce-alert"><?php echo wp_kses_post( sprintf( 'Добавьте товаров еще на %s — доставка может стать бесплатной.', wc_price( $remaining ) ) ); ?></div>
<?php else : ?>
<div class="water-commerce-alert is-success"><?php esc_html_e( 'Отлично: сумма заказа подходит под бесплатную доставку, если это доступно в вашей зоне.', 'twentytwentyfour' ); ?></div>
<?php endif; ?>
<div class="water-commerce-alert"><?php esc_html_e( 'Если используете новую бутыль без обмена, залог за тару будет показан отдельной строкой.', 'twentytwentyfour' ); ?></div>
</div>
<?php if ( is_user_logged_in() && $account_url ) : ?>
<div class="water-commerce-repeat-order"><a class="ghost-button" href="<?php echo esc_url( $account_url ); ?>"><?php esc_html_e( 'Повторить прошлый заказ', 'twentytwentyfour' ); ?></a></div>
<?php endif; ?>
</div>
<?php
}
/**
* Rename default cross-sells heading for water delivery cart.
*
* @param string $heading Default heading.
* @return string
*/
function twentytwentyfour_water_delivery_cross_sells_heading( $heading ) {
return __( 'Добавьте к заказу помпы, стаканы и оборудование', 'twentytwentyfour' );
}
/**
* Preserve Woo total html while allowing custom wrapper styling.
*
* @param string $value Current total html.
* @return string
*/
function twentytwentyfour_water_delivery_cart_totals_order_total_html( $value ) {
return '<span class="water-order-total-value">' . $value . '</span>';
}
/**
* Add a sticky summary note before cart totals.
*
* @return void
*/
function twentytwentyfour_water_delivery_before_cart_totals() {
?>
<div class="water-cart-summary-box">
<div class="water-cart-summary-usp"><?php esc_html_e( 'Доставка воды по Севастополю за 2-4 часа', 'twentytwentyfour' ); ?></div>
<ul class="water-cart-summary-list">
<li><?php esc_html_e( 'Стоимость доставки рассчитывается автоматически по зоне', 'twentytwentyfour' ); ?></li>
<li><?php esc_html_e( 'Залог за тару показывается отдельной строкой при необходимости', 'twentytwentyfour' ); ?></li>
<li><?php esc_html_e( 'После проверки корзины можно сразу перейти к оформлению', 'twentytwentyfour' ); ?></li>
</ul>
</div>
<?php
}
/**
* Add SEO content after the cart.
*
* @return void
*/
function twentytwentyfour_water_delivery_after_cart() {
?>
<section class="water-seo-copy-section water-seo-copy-section-cart">
<h2><?php esc_html_e( 'Доставка воды в Севастополе: оформить заказ онлайн', 'twentytwentyfour' ); ?></h2>
<p><?php echo esc_html( twentytwentyfour_water_delivery_seo_copy( 'cart' ) ); ?></p>
</section>
<?php
}
/**
* Add order CTA hints before submit button.
*
* @return void
*/
function twentytwentyfour_water_delivery_before_submit() {
?>
<div class="water-checkout-submit-box">
<div class="water-checkout-submit-note"><?php esc_html_e( 'Доставим сегодня при заказе до 18:00 в доступных районах Севастополя.', 'twentytwentyfour' ); ?></div>
<ul class="water-checkout-submit-list">
<li><?php esc_html_e( 'Телефон нужен для быстрого подтверждения заказа', 'twentytwentyfour' ); ?></li>
<li><?php esc_html_e( 'Стоимость доставки рассчитывается по зоне WooCommerce', 'twentytwentyfour' ); ?></li>
<li><?php esc_html_e( 'Залог за тару показывается отдельной строкой, если нет обмена', 'twentytwentyfour' ); ?></li>
</ul>
</div>
<?php
}
/**
* Customize the empty cart message.
*
* @return string
*/
function twentytwentyfour_water_delivery_empty_cart_message() {
return __( 'Корзина пока пуста. Перейдите в каталог и выберите воду 19 литров, питьевую воду или дополнительные товары для доставки по Севастополю.', 'twentytwentyfour' );
}
/**
* Add custom CTA below empty cart message.
*
* @return void
*/
function twentytwentyfour_water_delivery_empty_cart_cta() {
if ( ! function_exists( 'is_cart' ) || ! is_cart() || ! WC()->cart || ! WC()->cart->is_empty() ) {
return;
}
?>
<div class="water-empty-cart-cta"><a class="button" href="<?php echo esc_url( home_url( '/#catalog' ) ); ?>"><?php esc_html_e( 'Перейти в каталог', 'twentytwentyfour' ); ?></a></div>
<?php
}
/**
* Customize page title for cart and checkout if no SEO plugin is active.
*
* @param string $title Document title.
* @return string
*/
function twentytwentyfour_water_delivery_document_title( $title ) {
if ( twentytwentyfour_has_seo_plugin() ) {
return $title;
}
if ( function_exists( 'is_checkout' ) && is_checkout() && ! is_order_received_page() ) {
return 'Оформить заказ воды в Севастополе - доставка 19л на дом';
}
if ( function_exists( 'is_cart' ) && is_cart() ) {
return 'Корзина - заказать воду 19 литров с доставкой по Севастополю';
}
return $title;
}
/**
* Add fallback meta description and schema for cart/checkout.
*
* @return void
*/
function twentytwentyfour_water_delivery_meta_and_schema() {
if ( twentytwentyfour_has_seo_plugin() ) {
return;
}
if ( ! ( ( function_exists( 'is_checkout' ) && is_checkout() && ! is_order_received_page() ) || ( function_exists( 'is_cart' ) && is_cart() ) ) ) {
return;
}
$description = 'Быстрая доставка питьевой воды по Севастополю. Закажите воду 19 литров с доставкой на дом или в офис. Удобная оплата.';
if ( function_exists( 'is_cart' ) && is_cart() ) {
$description = 'Проверьте корзину и оформите заказ воды в Севастополе. Вода 19 литров, питьевая и минеральная вода с доставкой на дом или в офис.';
}
$schema = array(
'@context' => 'https://schema.org',
'@graph' => array(
array(
'@type' => 'LocalBusiness',
'name' => get_bloginfo( 'name' ),
'telephone' => '+7 (978) 123-45-67',
'address' => array(
'@type' => 'PostalAddress',
'addressLocality' => 'Севастополь',
'addressCountry' => 'RU',
),
'areaServed' => array( 'Гагаринский район', 'Ленинский район', 'Нахимовский район', 'Балаклава' ),
),
array(
'@type' => 'Product',
'name' => 'Вода 19 литров с доставкой',
'description' => 'Питьевая вода с доставкой на дом и в офис по Севастополю.',
'offers' => array(
'@type' => 'Offer',
'priceCurrency' => 'RUB',
'availability' => 'https://schema.org/InStock',
),
'aggregateRating' => array(
'@type' => 'AggregateRating',
'ratingValue' => '4.9',
'reviewCount' => '87',
),
),
),
);
?>
<meta name="description" content="<?php echo esc_attr( $description ); ?>">
<script type="application/ld+json"><?php echo wp_json_encode( $schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ); ?></script>
<?php
}