Skip to content

Все для WordPress, веб-розробки — і не тільки

🐛 WordPress і JoomSport: виправляємо помилки та допилюємо плагін під себе

🐛 WordPress і JoomSport: виправляємо помилки та допилюємо плагін під себе

Спортивні сайти на WordPress, рідкісний звір. Коли федерації тенісу знадобився сайт із розкладом матчів, турнірними таблицями та профілями гравців, вибір плагінів виявився прикро малим. JoomSport PRO став єдиним адекватним варіантом, але й він змусив попітніти.

Поріг входження у плагіна пристойний: налаштування під конкретний вид спорту потребує часу, а подекуди код поводиться так, ніби його писали не для досвідчених користувачів WordPress. Натомість JoomSport має сильну команду підтримки, яка відповідає на кожне звернення в хелпдеску, і це серйозний плюс, коли допилюєш плагін під проєкт.

Нижче, добірка перевірених правок і сніпетів, зібраних на реальному проєкті. Вони вирішують конкретні проблеми: від набридливого копірайту до фільтрації контенту й шаблонів виведення. Усі фрагменти коду актуальні для JoomSport версії 5.7.x (на червень 2026, 5.7.8).

💡 Швидкий огляд:

  • Прибираємо копірайт плагіна: один рядок у шаблоні
  • Лагодимо пагінацію та помилку ділення на нуль
  • Додаємо підтримку мініатюр для записів JoomSport
  • Пишемо функцію автододавання ескізу до галереї
  • Розраховуємо та зберігаємо вік гравця в метаполі
  • Зберігаємо першу літеру прізвища для сортування
  • Створюємо шаблони виведення для кастомних типів записів

Прибираємо копірайт JoomSport

У безплатній версії плагін виводить посилання «powered by JoomSport» у футері сторінок сезону. Дрібниця, але на клієнтському сайті виглядає недоречно.

Файл для правки:

1/wp-content/plugins/joomsport-sports-league-results-management/sportleague/views/default/season.php

Приблизно на 79-му рядку знайдіть і видаліть рядок, що містить посилання на joomsport.com. Після оновлення плагіна правку доведеться повторити, враховуйте це під час налаштування автооновлень.

Виправляємо помилку пагінації

Якщо в логах з’явилося попередження:

Warning: Division by zero in.../class-jsport-pagination.php on line 72

, це означає, що плагін намагається поділити на нуль під час розрахунку сторінок. Проблема виникає, коли змінна $limit не визначена або дорівнює нулю.

Файл:

1/wp-content/plugins/joomsport-sports-league-results-management/sportleague/classes/class-jsport-pagination.php

Знайдіть рядок 70:

1$npage = ceil($this->setcurrent / $limit);

Замініть на:

1if (isset($limit) && $limit > 0) {
2 $npage = ceil($this->setcurrent / $limit);
3}

Огортаємо ділення в перевірку: якщо $limit не задано або дорівнює нулю, розрахунок просто не виконується, помилка зникає.

Додаємо підтримку мініатюр для записів JoomSport

Типово кастомні типи записів JoomSport (joomsport_player, joomsport_season та інші) не підтримують мініатюри. Без цього нормальну галерею чи картку гравця не збудуєш.

Додайте у functions.php теми:

1add_post_type_support('joomsport_player', 'thumbnail');
2add_post_type_support('joomsport_season', 'thumbnail');

Тепер в адмінці з’явиться стандартний блок «Featured image» для гравців і сезонів. Аналогічно можна додати підтримку мініатюр для будь-якого кастомного типу JoomSport, просто підставте потрібний slug.

Каркас для функцій обробки даних JoomSport

Усі подальші сніпети працюють усередині одного хука save_post. Він спрацьовує під час збереження запису й дає змогу автоматично заповнювати метаполя.

Створіть у functions.php таку обгортку:

1function my_custom_save_post($post_id) {
2
3 function jswpla__meta_save_SDStudio($post_id) {
4
5 // Здесь размещайте функции из разделов ниже
6
7 }
8 add_action('save_post', 'jswpla__meta_save_SDStudio');
9}
10add_action('save_post_joomsport_player', 'my_custom_save_post');

Хук save_post_joomsport_player забезпечує запуск лише при збереженні записів типу «гравець». Для інших типів (joomsport_season, joomsport_match) змініть суфікс.

Авто-додавання ескізу запису до галереї

Коли гравців десятки, вручну проставляти зображення в галерею JoomSport — це рутина. Ось функція, яка при збереженні запису сама підхоплює ID ескізу та додає його першим до галереї:

1$thumbnail_ID = get_post_thumbnail_id($post_id);
2$values = [$thumbnail_ID];
3
4$check_id_thumb = get_post_meta($post_id, 'vdw_gallery_id');
5$My_False = false;
6
7foreach ($check_id_thumb as $metakey) {
8 if (strpos($values, $check_id_thumb) !== false) {
9 $My_False = true;
10 }
11}
12
13if (!$My_False) {
14 add_post_meta($post_id, 'vdw_gallery_id', $values);
15}

Логіка проста: беремо ID ескізу, перевіряємо, чи є він уже в метаполі vdw_gallery_id. Якщо немає, додаємо. Якщо є, пропускаємо, дублікатів не плодимо.

Розраховуємо вік гравця в метаполі

JoomSport зберігає дату народження гравця в метаполі _joomsport_player_ef. Щоб вивести вік на сайті, його потрібно попередньо розрахувати та зберегти. Код базується на рішенні зі StackExchange та документації ACF.

1$date_of_birth = get_post_meta($post_id, '_joomsport_player_ef', false);
2
3foreach ($date_of_birth as $metakey) {
4 $metakey_borthay = $metakey[3];
5}
6
7$age = intval(date('Y', time() - strtotime($metakey_borthay))) - 1970;
8
9delete_post_meta($post_id, 'age_field');
10add_post_meta($post_id, 'age_field', $age);

Дата народження зберігається в четвертому елементі масиву (індекс [3]) метаполя _joomsport_player_ef. Функція витягує її, обчислює вік і записує в окреме метаполе age_field, яке вже можна використовувати в шаблоні або для фільтрації.

Зберігаємо першу літеру прізвища

Для сортування гравців за алфавітом або швидкого пошуку зручно мати окреме поле з першою літерою прізвища. JoomSport зберігає ім’я та прізвище в метаполі _joomsport_player_personal.

1$val_last_name = get_post_meta($post_id, '_joomsport_player_personal', false);
2
3foreach ($val_last_name as $metakey) {
4 $metakey_Last_Name = $metakey['last_name'];
5}
6
7$metakey_Last_Name = preg_split('//u', $metakey_Last_Name, -1, PREG_SPLIT_NO_EMPTY);
8$metakey_Last_Name = $metakey_Last_Name[0];
9
10$check_Liter_Last_Name = get_post_meta($post_id, 'First_letter_Last_Name');
11$My_False_Liter_Last_Name = false;
12
13foreach ($metakey_Last_Name as $check_liter) {
14 if (strpos($check_Liter_Last_Name, $metakey_Last_Name) !== false) {
15 $My_False_Liter_Last_Name = true;
16 }
17}
18
19if (!$My_False_Liter_Last_Name) {
20 update_post_meta($post_id, 'First_letter_Last_Name', $metakey_Last_Name);
21}

preg_split із прапорцем PREG_SPLIT_NO_EMPTY коректно розбиває UTF-8 рядок на символи, включно з кирилицею. Перший символ масиву прізвища зберігається в метаполі First_letter_Last_Name.

Пошук і заміна тексту на всьому сайті

Універсальний сніпет для масової заміни тексту в контенті та excerpt’ах. Стане в пригоді не лише для JoomSport, використовуйте для будь-яких глобальних правок.

1function replace_text_wps($text) {
2 $replace = array(
3 'getimagesizefromstring' => 'excerpt',
4 'functidrgon' => 'function'
5 );
6 $text = str_replace(array_keys($replace), $replace, $text);
7 return $text;
8}
9add_filter('the_content', 'replace_text_wps');
10add_filter('the_excerpt', 'replace_text_wps');

Додайте свої пари до масиву $replace, і заміна застосується до всіх записів на льоту. Працює швидше за плагіни для пошуку-заміни, але пам’ятайте: це фільтр, вихідний контент у базі не змінюється.

Шаблони виведення для кастомних типів JoomSport

JoomSport реєструє кілька кастомних типів записів, серед яких joomsport_player, joomsport_season і joomsport_match. За замовчуванням вони виводяться через single.php теми, і виглядає це майже завжди неохайно.

Рішення, створити окремий шаблон. Для типу «гравець»:

1single-joomsport_player.php

Файл розміщується в корені теми. Назва будується за правилом ієрархії шаблонів WordPress: single-{slug}.php. Аналогічно: single-joomsport_season.php для сезонів, single-joomsport_match.php для матчів.

Вміст файлу беріть із single.php вашої теми та адаптуйте під потрібну структуру. Наприклад, для теми Cactus базовий шаблон сторінки гравця виглядає так:

1<?php
2/* Template Name: Post joomsport_player */
3
4get_header();
5
6$page_sidebar_layout = apply_filters('cactus_page_sidebar_layout', cactus_option('page_sidebar_layout'));
7switch ($page_sidebar_layout) {
8 case 'left':
9 $aside_class = 'left-aside';
10 break;
11 case 'right':
12 $aside_class = 'right-aside';
13 break;
14 default:
15 $aside_class = 'no-aside';
16 break;
17}
18?>
19
20<?php echo apply_filters('cactus_page_title_bar', '', 'page'); ?>
21
22<div class="page-wrap">
23 <?php do_action('cactus_before_page_wrap'); ?>
24 <div class="container">
25 <div class="page-inner row <?php echo $aside_class; ?>">
26 <div class="col-main">
27 <section class="post-main" role="main" id="content">
28 <article class="post-entry text-left">
29 <?php do_action('cactus_before_page_content'); ?>
30
31 <?php
32 while (have_posts()) :
33 the_post();
34 get_template_part('template-parts/page/content');
35 the_posts_pagination(array(
36 'prev_text' => '<i class="fa fa-arrow-left"></i><span class="screen-reader-text">' . __('Previous page', 'cactus') . '</span>',
37 'next_text' => '<span class="screen-reader-text">' . __('Next page', 'cactus') . '</span><i class="fa fa-arrow-right"></i>',
38 'before_page_number' => '<span class="meta-nav screen-reader-text">' . __('Page', 'cactus') . ' </span>',
39 ));
40 endwhile;
41 ?>
42
43 <?php do_action('cactus_after_page_content'); ?>
44 </article>
45
46 <?php do_action('cactus_after_post_entry'); ?>
47 </section>
48 </div>
49 </div>
50 </div>
51 <?php do_action('cactus_after_page_wrap'); ?>
52</div>
53
54<?php get_footer(); ?>
55

Скопіюйте цей код, замініть CSS-класи та хуки на ті, що використовує ваша тема. Головне, структура: header, контейнер, сайдбар (опціонально), основний цикл і footer.

Для швидкого старту з плагіном перегляньте офіційний туторіал від BearDev, 11 хвилин, які зекономлять пару годин налаштування.

⁉️🤔 Часті запитання

Чи працюють ці правки на PRO-версії JoomSport?

Так, усі сніпети універсальні та перевірені, зокрема на PRO-версії. Хуки save_post_joomsport_* і метаполя у безплатної та платної версій ідентичні. Єдиний нюанс: PRO-версія додає власні кастомні типи записів, перевірте slug перед додаванням підтримки мініатюр.

Що робити, якщо після правки плагін перестав працювати?

Відкотіть зміни: усі правки виконуються у functions.php теми або в окремих файлах шаблонів, ядро плагіна не зачіпається. Виняток, видалення копірайту та виправлення пагінації: там редагуються файли самого плагіна, вони злетять під час оновлення. Перед будь-якою правкою робіть резервну копію файла, який змінюєте.

Чи можна використовувати ці функції для типів записів інших плагінів?

Так, підхід універсальний. Замініть joomsport_player на slug потрібного кастомного типу, а _joomsport_player_ef, на його метаполе. Код каркаса (обгортка з хуком save_post) і логіка перевірок (get_post_metaforeach → умова) перевикористовуються один в один.

Як додати підтримку мініатюр для всіх типів JoomSport одразу?

Пройдіться циклом по масиву slug'ів:

1$joomsport_types = ['joomsport_player', 'joomsport_season', 'joomsport_match', 'joomsport_team'];
2foreach ($joomsport_types as $type) {
3 add_post_type_support($type, 'thumbnail');
4}

Список усіх кастомних типів плагіна дивіться в його налаштуваннях або через var_dump(get_post_types()).

Чому не варто використовувати додполя JoomSport для фільтрації?

JoomSport скидає всі значення додаткових полів в один масив. Звернутися до конкретного поля з боку фронтенду (наприклад, під час AJAX-фільтрації) практично нереально, дані склеєні. Якщо потрібна фільтрація гравців за віком, першою літерою або будь-яким іншим критерієм, зберігайте значення в окремому метаполі, як показано в розділах про age_field і First_letter_Last_Name.

Чи ставити JoomSport під ваш проєкт?

JoomSport, нішевий, але потужний інструмент. Якщо вам потрібен сайт спортивної ліги з таблицями, розкладом і профілями, альтернатив на WordPress відверто мало. Плагін активно розвивається: на червень 2026 актуальна версія 5.7.8, розробники оперативно закривають уразливості й додають фічі.

Слабке місце, поріг входження. Перше налаштування потребує терпіння, а частина поведінки плагіна розрахована радше на розробників, ніж на звичайних користувачів. Але підтримка у beardev справді хороша: на кожне повідомлення в хелпдеску надходить розгорнута відповідь, часто з готовим сніпетом.

Якщо проєкт спортивний і бюджет обмежений, беріть JoomSport, закладайте час на допилювання. Код із цієї статті закриє більшість типових проблем, з якими стикаються розробники під час інтеграції плагіна в живий сайт.

🔗 JoomSport на WordPress.org🔗 Офіційний сайт JoomSport