515 lines
19 KiB
PHP
515 lines
19 KiB
PHP
<?php
|
||
setlocale(LC_TIME, 'ru_RU.UTF-8');
|
||
|
||
require get_template_directory().'/dzenews.php'; //add support dzen
|
||
|
||
function theme_setup()
|
||
{
|
||
add_theme_support('menus');
|
||
register_nav_menus(array(
|
||
'primary' => __('Основное меню', 'your-theme-domain'),
|
||
'socials' => __('Соцсети', 'your-theme-domain'),
|
||
'footer-bottom' => __('Нижнее меню в подвале', 'your-theme-domain'),
|
||
));
|
||
|
||
add_theme_support('custom-logo', array(
|
||
'height' => 100,
|
||
'width' => 400,
|
||
'flex-height' => true,
|
||
'flex-width' => true,
|
||
));
|
||
|
||
add_theme_support('post-thumbnails');
|
||
}
|
||
add_action('after_setup_theme', 'theme_setup');
|
||
|
||
function theme_enqueue_styles_scripts()
|
||
{
|
||
$style_ver = filemtime(get_template_directory() . '/frontend/dist/assets/main.css');
|
||
$script_ver = filemtime(get_template_directory() . '/frontend/dist/assets/main2.js');
|
||
|
||
|
||
wp_enqueue_style('main-style', get_template_directory_uri() . '/frontend/dist/assets/main.css', array(), $style_ver);
|
||
wp_enqueue_script('main-script2', get_template_directory_uri() . '/frontend/dist/assets/main2.js', array(), $script_ver, true);
|
||
|
||
// Preconnect for Google Fonts
|
||
//wp_enqueue_style('google-fonts-preconnect', 'https://fonts.gstatic.com', [], null, 'all');
|
||
//wp_resource_hints(['https://fonts.googleapis.com', 'https://fonts.gstatic.com'], 'preconnect');
|
||
|
||
// Enqueue Google Fonts
|
||
wp_enqueue_style('google-fonts-raleway', 'https://fonts.googleapis.com/css2?family=Raleway:wght@400;500;600&display=swap', false);
|
||
wp_enqueue_style('google-fonts-roboto', 'https://fonts.googleapis.com/css2?family=Roboto:wght@400&display=swap', false);
|
||
}
|
||
add_action('wp_enqueue_scripts', 'theme_enqueue_styles_scripts');
|
||
|
||
add_filter('nav_menu_css_class', 'change_menu_item_css_class', 10, 4);
|
||
function change_menu_item_css_class($classes, $item, $args, $depth)
|
||
{
|
||
// Удаляем нежелательные классы
|
||
$classes = array_diff($classes, array('page_item', 'page-item-' . $item->ID));
|
||
$classes = array_diff($classes, array('page_item', 'page-item-' . $item->ID));
|
||
|
||
// Добавляем класс 'menu-item'
|
||
$classes[] = 'menu-item';
|
||
|
||
return $classes;
|
||
}
|
||
|
||
function get_asset(string $path)
|
||
{
|
||
return get_template_directory_uri() . '/frontend/dist/' . $path;
|
||
}
|
||
|
||
function mytheme_widget_areas()
|
||
{
|
||
// Регистрация левого сайдбара
|
||
register_sidebar(array(
|
||
'name' => 'Левый сайдбар',
|
||
'id' => 'left-sidebar',
|
||
'description' => 'Виджеты в этой области будут показаны в левой части сайта.',
|
||
'before_widget' => '<div id="%1$s" class="widget %2$s">',
|
||
'after_widget' => '</div>',
|
||
'before_title' => '<h3 class="widget-title">',
|
||
'after_title' => '</h3>',
|
||
));
|
||
|
||
// Регистрация правого сайдбара
|
||
register_sidebar(array(
|
||
'name' => 'Правый сайдбар',
|
||
'id' => 'right-sidebar',
|
||
'description' => 'Виджеты в этой области будут показаны в правой части сайта.',
|
||
'before_widget' => '<div id="%1$s" class="widget %2$s">',
|
||
'after_widget' => '</div>',
|
||
'before_title' => '<h3 class="widget-title">',
|
||
'after_title' => '</h3>',
|
||
));
|
||
}
|
||
add_action('widgets_init', 'mytheme_widget_areas');
|
||
|
||
|
||
class Upcoming_Events_Widget extends WP_Widget
|
||
{
|
||
function __construct()
|
||
{
|
||
parent::__construct(
|
||
'upcoming_events_widget', // ID виджета
|
||
'Upcoming Events', // Название виджета
|
||
array('description' => 'Displays upcoming events') // Описание
|
||
);
|
||
}
|
||
|
||
public function widget($args, $instance)
|
||
{
|
||
include get_template_directory() . '/widgets/upcoming-events-widget-template.php';
|
||
}
|
||
|
||
// Форма в админ-панели для настройки виджета
|
||
public function form($instance)
|
||
{
|
||
$title = !empty($instance['title']) ? $instance['title'] : 'Новое название';
|
||
?>
|
||
<p>
|
||
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>">Название:</label>
|
||
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr($title); ?>">
|
||
</p>
|
||
<?php
|
||
}
|
||
|
||
// Сохранение настроек виджета
|
||
public function update($new_instance, $old_instance)
|
||
{
|
||
$instance = array();
|
||
$instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
|
||
return $instance;
|
||
}
|
||
}
|
||
|
||
function register_upcoming_events_widget()
|
||
{
|
||
register_widget('Upcoming_Events_Widget');
|
||
}
|
||
add_action('widgets_init', 'register_upcoming_events_widget');
|
||
add_action('widgets_init', 'register_upcoming_events_widget');
|
||
|
||
function format_event_date()
|
||
{
|
||
$post_date = get_the_date('Y-m-d');
|
||
$current_date = date('Y-m-d');
|
||
$tomorrow_date = date('Y-m-d', strtotime('+1 day', strtotime($current_date)));
|
||
|
||
if ($post_date == $current_date) {
|
||
$date_text = 'сегодня';
|
||
} elseif ($post_date == $tomorrow_date) {
|
||
$date_text = 'завтра';
|
||
} else {
|
||
$date_text = get_the_date();
|
||
}
|
||
|
||
$time = get_the_time('H:i');
|
||
|
||
return $date_text . ', ' . $time;
|
||
}
|
||
|
||
/**
|
||
* Фильтр для изменения разметки хлебных крошек Yoast SEO.
|
||
*/
|
||
add_filter('wpseo_breadcrumb_output', 'custom_wpseo_breadcrumb_output');
|
||
function custom_wpseo_breadcrumb_output($output)
|
||
{
|
||
// Заменяем начальный тег разметки.
|
||
$output = str_replace('<span><span>', '', $output);
|
||
$output = str_replace('</span></span>', '', $output);
|
||
// Заменяем разделитель на нужный нам класс.
|
||
$output = str_replace('»', '', $output);
|
||
// Заменяем теги ссылок.
|
||
$output = str_replace('<a', '<a class="breadcrumbs__item"', $output);
|
||
// Заменяем тег последнего элемента (текущей страницы) на span с классом.
|
||
$output = preg_replace('/<span class="breadcrumb_last"[^>]*>/', '<span class="breadcrumbs__item">', $output);
|
||
|
||
return $output;
|
||
}
|
||
|
||
|
||
|
||
function custom_pagination($query = null)
|
||
{
|
||
global $wp_query;
|
||
$query = $query ?: $wp_query;
|
||
$current_page = max(1, get_query_var('paged'));
|
||
$total_pages = $query->max_num_pages;
|
||
|
||
$show_items = 3; // Количество страниц для вывода в начале и в конце
|
||
$range = 1; // Диапазон страниц вокруг текущей страницы
|
||
|
||
if (1 == $total_pages) {
|
||
return; // Если страница всего одна, пагинация не нужна
|
||
}
|
||
|
||
echo '<div class="pagination"><div class="pagination__list">';
|
||
|
||
// Кнопка "Назад"
|
||
if ($current_page > 1) {
|
||
$prev_page_link = get_pagenum_link($current_page - 1);
|
||
echo "<a href='" . esc_url($prev_page_link) . "' class=\"pagination__btn\">« Назад</a>";
|
||
}
|
||
|
||
// Начало пагинации
|
||
for ($i = 1; $i <= $total_pages; $i++) {
|
||
// Условие для предотвращения дублирования начальных страниц
|
||
if ($total_pages > ($show_items * 2) && $i > $show_items && $i < $total_pages - $show_items + 1) {
|
||
if ($i == $current_page - $range - 1 || $i == $current_page + $range + 1) {
|
||
echo "<span class=\"pagination__item\">...</span>"; // Многоточие
|
||
continue;
|
||
}
|
||
}
|
||
|
||
if ($i == $current_page) {
|
||
echo "<span class=\"pagination__item is-active\">$i</span>"; // Текущая страница
|
||
} elseif ($i <= $show_items || ($i >= $total_pages - $show_items + 1) || ($i >= $current_page - $range && $i <= $current_page + $range)) {
|
||
echo "<a href='" . get_pagenum_link($i) . "' class=\"pagination__item\">$i</a>";
|
||
}
|
||
}
|
||
|
||
// Кнопка "Далее"
|
||
if ($current_page < $total_pages) {
|
||
$next_page_link = get_pagenum_link($current_page + 1);
|
||
echo "<a href='" . esc_url($next_page_link) . "' class=\"pagination__btn\">Далее »</a>";
|
||
}
|
||
|
||
echo '</div></div>';
|
||
}
|
||
|
||
function my_theme_scripts()
|
||
{
|
||
wp_enqueue_script('my-load-more', get_template_directory_uri() . '/js/load-more.js', array('jquery'), null, true);
|
||
|
||
$query = new WP_Query(array('post_type' => 'post', 'posts_per_page' => 10));
|
||
|
||
// Передаем переменные в скрипт
|
||
wp_localize_script('my-load-more', 'my_load_more_params', array(
|
||
'ajaxurl' => admin_url('admin-ajax.php'), // URL для AJAX-запроса
|
||
'posts' => json_encode($query->query_vars), // Параметры запроса
|
||
'current_page' => get_query_var('paged') ? get_query_var('paged') : 1, // Текущая страница
|
||
'max_page' => $query->max_num_pages // Максимальное количество страниц
|
||
));
|
||
}
|
||
add_action('wp_enqueue_scripts', 'my_theme_scripts');
|
||
|
||
|
||
function loadmore_ajax_handler()
|
||
{
|
||
$args = json_decode(stripslashes($_POST['query']), true);
|
||
$args['paged'] = $_POST['page'] + 1; // следующая страница
|
||
$args['post_status'] = 'publish';
|
||
$args['cat'] = [-17, -20, -21];
|
||
|
||
query_posts($args);
|
||
|
||
if (have_posts()) :
|
||
while (have_posts()) : the_post();
|
||
get_template_part('content', 'post');
|
||
endwhile;
|
||
endif;
|
||
die;
|
||
}
|
||
add_action('wp_ajax_loadmore', 'loadmore_ajax_handler'); // для авторизованных пользователей
|
||
add_action('wp_ajax_nopriv_loadmore', 'loadmore_ajax_handler'); // для неавторизованных пользователей
|
||
|
||
/*
|
||
* Фильтр добавлен для модификации стандартной формы плагина Contact Form ( Срезаем span элементы, в которые оборачивается input ).
|
||
* Работает в связке с отключенными требованиями плагина - define( 'WPCF7_AUTOP', false );
|
||
* В файле wp-config.php
|
||
* */
|
||
add_filter('wpcf7_form_elements', function ($content) {
|
||
$content = preg_replace('/<(span).*?class="\s*(?:.*\s)?wpcf7-form-control-wrap(?:\s[^"]+)?\s*"[^\>]*>(.*)<\/\1>/i', '\2', $content);
|
||
return $content;
|
||
});
|
||
|
||
function show_post_image($post = null, $size = 'large')
|
||
{
|
||
if (has_post_thumbnail($post)) {
|
||
return get_the_post_thumbnail($post, $size);
|
||
} else {
|
||
return '<img src="' . get_template_directory_uri() . '/noimage.jpg">';
|
||
}
|
||
}
|
||
|
||
add_action('rest_api_init', function () {
|
||
register_rest_route('agroexpert/v1', '/posts-by-date/', array(
|
||
'methods' => 'GET',
|
||
'callback' => 'get_posts_by_date',
|
||
'permission_callback' => '__return_true', // Доступно для чтения всеми
|
||
));
|
||
});
|
||
|
||
|
||
function get_posts_by_date($request)
|
||
{
|
||
global $wpdb; // Глобальный объект базы данных WordPress
|
||
|
||
// SQL-запрос для получения уникальных дат публикации постов
|
||
$query = "
|
||
SELECT DISTINCT DATE(post_date) as date
|
||
FROM {$wpdb->posts}
|
||
WHERE post_status IN ('publish', 'future')
|
||
AND post_type = 'post'
|
||
ORDER BY date DESC
|
||
";
|
||
|
||
// Выполнение запроса
|
||
$result = $wpdb->get_results($query);
|
||
|
||
// Преобразование результатов в массив дат
|
||
$dates = array_map(function ($item) {
|
||
return $item->date;
|
||
}, $result);
|
||
|
||
return new WP_REST_Response($dates, 200);
|
||
}
|
||
|
||
function setup_future_hook()
|
||
{
|
||
// Replace native future_post function with replacement
|
||
remove_action('future_event', '_future_post_hook');
|
||
add_action('future_event', 'publish_future_post_now');
|
||
}
|
||
|
||
function publish_future_post_now($id)
|
||
{
|
||
// Set new post's post_status to "publish" rather than "future."
|
||
wp_publish_post($id);
|
||
}
|
||
|
||
add_action('init', 'setup_future_hook');
|
||
|
||
add_action('restrict_manage_posts', 'add_author_filter_to_posts_admin');
|
||
|
||
function add_author_filter_to_posts_admin()
|
||
{
|
||
global $post_type;
|
||
|
||
// Убедитесь, что этот фильтр применяется только к типу поста 'post'
|
||
if ('post' !== $post_type) {
|
||
return;
|
||
}
|
||
|
||
// Получаем пользователей с ролью 'author'
|
||
$authors = get_users(array('role' => '', 'orderby' => 'display_name', 'order' => 'ASC'));
|
||
|
||
// Проверяем, установлен ли фильтр
|
||
$selected = isset($_GET['custom_author']) ? $_GET['custom_author'] : '';
|
||
|
||
// Начинаем выводить HTML выпадающего списка
|
||
echo '<select name="custom_author">';
|
||
echo '<option value="">Все авторы</option>';
|
||
|
||
// Перебираем всех авторов и добавляем их в выпадающий список
|
||
foreach ($authors as $author) {
|
||
$display_name = $author->display_name; // Отображаемое имя для отображения
|
||
$user_id = $author->ID; // ID пользователя для значения опции
|
||
echo sprintf(
|
||
'<option value="%s"%s>%s</option>',
|
||
esc_attr($user_id),
|
||
selected($selected, $user_id, false),
|
||
esc_html($display_name)
|
||
);
|
||
}
|
||
|
||
echo '</select>';
|
||
}
|
||
|
||
add_action('pre_get_posts', 'filter_posts_by_custom_author');
|
||
|
||
function filter_posts_by_custom_author($query)
|
||
{
|
||
global $pagenow;
|
||
|
||
// Применяем фильтр только в админ-панели и только для основного запроса на странице списка постов
|
||
if (is_admin() && 'edit.php' === $pagenow && $query->is_main_query()) {
|
||
// Проверяем, установлен ли наш фильтр
|
||
if (!empty($_GET['custom_author'])) {
|
||
$custom_author_id = $_GET['custom_author'];
|
||
|
||
// Фильтруем посты по автору
|
||
$query->set('author', $custom_author_id);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
function custom_search_rewrite_rule()
|
||
{
|
||
add_rewrite_rule(
|
||
'^search/$',
|
||
'index.php?s=' . get_query_var('s'),
|
||
'top'
|
||
);
|
||
add_rewrite_rule('^search/?$', 'index.php?s=', 'top');
|
||
|
||
add_rewrite_rule('^search/page/([0-9]+)/?$', 'index.php?s=&paged=$matches[1]', 'top');
|
||
}
|
||
add_action('init', 'custom_search_rewrite_rule');
|
||
|
||
add_filter('relevanssi_hits_filter', 'rlv_gather_categories', 99);
|
||
function rlv_gather_categories($hits)
|
||
{
|
||
global $rlv_categories_present;
|
||
$rlv_categories_present = array();
|
||
foreach ($hits[0] as $hit) {
|
||
$terms = get_the_terms($hit->ID, 'category');
|
||
if (is_array($terms)) {
|
||
foreach ($terms as $term) {
|
||
$rlv_categories_present[$term->term_id] = $term->name;
|
||
}
|
||
}
|
||
}
|
||
asort($rlv_categories_present);
|
||
return $hits;
|
||
}
|
||
|
||
function plural_form_extended($number, $forms, $additionalWord = '')
|
||
{
|
||
$cases = array(2, 0, 1, 1, 1, 2);
|
||
$index = ($number % 100 > 4 && $number % 100 < 20) ? 2 : $cases[min($number % 10, 5)];
|
||
|
||
// Склонение дополнительного слова, если оно передано
|
||
$additionalForm = '';
|
||
if ($additionalWord) {
|
||
$additionalIndex = $index > 0 ? 1 : 0; // Простая логика для "найдено"
|
||
$additionalForm = $additionalWord[$additionalIndex] . ' ';
|
||
}
|
||
|
||
return $additionalForm . $number . ' ' . $forms[$index];
|
||
}
|
||
|
||
add_filter('wpseo_breadcrumb_links', 'custom_search_breadcrumbs');
|
||
|
||
function custom_search_breadcrumbs($links)
|
||
{
|
||
if (is_search()) {
|
||
// Получаем поисковый запрос
|
||
$search_query = get_search_query();
|
||
|
||
// Перебираем все ссылки, чтобы найти и изменить нужный элемент
|
||
foreach ($links as &$link) {
|
||
if (strpos($link['text'], 'Результаты поиска') !== false) {
|
||
if ($search_query === "") {
|
||
$link['text'] = 'Поиск';
|
||
} else {
|
||
$link['text'] = 'Результаты поиска для запроса "' . esc_html($search_query) . '"';
|
||
}
|
||
$link['url'] = home_url('/search/') . urlencode($search_query) . '/';
|
||
break; // Прерываем цикл после изменения нужного элемента
|
||
}
|
||
}
|
||
unset($link);
|
||
}
|
||
|
||
return $links;
|
||
}
|
||
|
||
function include_future_posts_in_date_archive($query)
|
||
{
|
||
// Убедимся, что мы находимся в основном запросе и на странице архива по дате
|
||
if ($query->is_main_query() && $query->is_date()) {
|
||
// Изменяем запрос так, чтобы он включал посты с датой публикации в будущем
|
||
$query->set('post_status', array('publish', 'future'));
|
||
}
|
||
}
|
||
add_action('pre_get_posts', 'include_future_posts_in_date_archive');
|
||
|
||
|
||
function template_500_error($template)
|
||
{
|
||
// Проверяем, является ли текущая страница страницей ошибки 500
|
||
if (is_500()) {
|
||
return get_stylesheet_directory() . '/500.php'; // Путь к вашему собственному шаблону 500 ошибки
|
||
}
|
||
return $template;
|
||
}
|
||
add_filter('template_include', 'template_500_error');
|
||
|
||
function is_500()
|
||
{
|
||
// Проверяем, является ли текущий код состояния HTTP 500
|
||
return get_query_var('error', false) === 500;
|
||
}
|
||
|
||
function change_image_size_dimensions()
|
||
{
|
||
update_option('large_size_w', 1080);
|
||
update_option('large_size_h', 0);
|
||
|
||
update_option('medium_size_w', 400);
|
||
update_option('medium_size_h', 0);
|
||
}
|
||
|
||
add_action('init', 'change_image_size_dimensions');
|
||
|
||
add_filter('big_image_size_threshold', '__return_false');
|
||
|
||
function auto_add_category_by_slug_to_new_post($post_ID, $post, $update)
|
||
{
|
||
$category_slug = 'all-events'; // Slug рубрики для добавления
|
||
$category = get_term_by('slug', $category_slug, 'category');
|
||
|
||
// Если рубрика с таким slug существует
|
||
if ($category && !has_category($category->term_id, $post_ID)) {
|
||
wp_set_post_categories($post_ID, array($category->term_id), true);
|
||
}
|
||
}
|
||
add_action('save_post', 'auto_add_category_by_slug_to_new_post', 10, 3);
|
||
|
||
|
||
function get_category_name($post = null)
|
||
{
|
||
$categories = get_the_category($post);
|
||
$categories = array_filter($categories, function (WP_Term $category) {
|
||
return $category->slug !== 'all-events';
|
||
});
|
||
$categories = array_values($categories);
|
||
$category_name = !empty($categories) ? esc_html($categories[0]->name) : 'Все события';
|
||
|
||
return $category_name;
|
||
}
|