Подробиці по коду дам в повідомлення особисті, сам код ось
логіка має бути такою:
Отримання рубрики запису:
- Вам потрібно визначити рубрику (або таксономію) для типу записів
price, де буде використовуватися ваш шорткод. Це дозволить вам згодом фільтрувати записи за цією рубрикою.
Отримання списку записів за рубрикою з заповненим ACF полем link_price:
- Далі, потрібно отримати всі записи з цієї рубрики, де заповнене поле Advanced Custom Fields (ACF)
link_price. Це означає, що ви будете виконувати запити до бази даних або використовувати функції WordPress для пошуку записів, які відповідають цим критеріям.
Формування цін для таблиці:
- Потрібно створити два варіанти формування цін для таблиці, залежно від кількості доступних даних по цінах на метали:
- Якщо по кожному металу окремо є більше 5 записів з ціною за останні 30 днів (з отриманих раніше записів), то ціна формується на основі цих даних.
- Якщо по металу менше 5 цін за останні 30 днів, то ціни в таблиці формуються на основі всіх доступних даних по цінах за останні 30 днів, без фільтрації за записами.
function scrap_metal_prices_shortcode($atts) {
global $wpdb;
$attributes = shortcode_atts([
'metal' => '',
], $atts);
$metals = explode(',', $attributes['metal']);
$post_id = get_the_ID();
$categories = wp_get_post_terms($post_id, 'category');
if (!empty($categories) && !is_wp_error($categories)) {
$category_id = $categories[0]->term_id;
}
$posts_with_prices = get_posts([
'post_type' => 'price',
'category' => $category_id,
'meta_query' => [
[
'key' => 'link_price',
'compare' => '!=',
'value' => ''
]
],
'fields' => 'ids'
]);
$valid_post_ids = implode(',', array_map('intval', $posts_with_prices));
$metal_prices_data = [];
foreach ($metals as $metal) {
$query = $wpdb->prepare("
SELECT COUNT(p.id) AS count, tm.metal_name
FROM {$wpdb->prefix}types_of_metal tm
LEFT JOIN {$wpdb->prefix}prices p ON tm.metal_id = p.metal_id AND p.post_id IN ($valid_post_ids)
WHERE tm.metal_name = %s AND p.date >= CURDATE() - INTERVAL 30 DAY
GROUP BY tm.metal_name
", $metal);
$result = $wpdb->get_row($query);
if ($result && $result->count >= 1) {
$metal_prices_data[$metal] = 'use_specific_posts';
} else {
$metal_prices_data[$metal] = 'use_all_posts';
}
}
// Виконуємо запит до бази даних для отримання цін за вказаною логікою
$prices_output = []; // Масив для зберігання результатів
foreach ($metal_prices_data as $metal => $data_source) {
if ($data_source === 'use_specific_posts') {
$query = $wpdb->prepare("
SELECT tm.metal_name, MAX(p.date) AS last_update,
AVG(p.value) AS average_price,
MAX(p.value) AS high_price,
MIN(p.value) AS low_price
FROM {$wpdb->prefix}types_of_metal tm
LEFT JOIN {$wpdb->prefix}prices p ON tm.metal_id = p.metal_id
WHERE tm.metal_name = %s AND p.post_id IN ($valid_post_ids) AND p.date >= CURDATE() - INTERVAL 30 DAY
GROUP BY tm.metal_name
", $metal);
} else {
$query = $wpdb->prepare("
SELECT tm.metal_name, MAX(p.date) AS last_update,
AVG(p.value) AS average_price,
MAX(p.value) AS high_price,
MIN(p.value) AS low_price
FROM {$wpdb->prefix}types_of_metal tm
LEFT JOIN {$wpdb->prefix}prices p ON tm.metal_id = p.metal_id
WHERE tm.metal_name = %s AND p.date >= CURDATE() - INTERVAL 30 DAY
GROUP BY tm.metal_name
", $metal);
}
$prices_output[$metal] = $wpdb->get_row($query);
}
// Початок таблиці
$output = '<table class="scrap-metal-prices">
<thead>
<tr>
<th rowspan="2">Назва металу</th>
<th>Найбільша ціна</th>
<th>Середня ціна</th>
<th>Найменша ціна</th>
<th rowspan="2">Дата оновлення</th>
</tr>
<tr>
<th colspan="3"><span class="currency-info">Ціна вказана в грн за 1 кг</span></th>
</tr>
</thead>
<tbody>';
// Масив з українськими назвами місяців
$ukrMonths = [
1 => 'січ', 2 => 'лют', 3 => 'бер', 4 => 'кві', 5 => 'тра', 6 => 'чер',
7 => 'лип', 8 => 'сер', 9 => 'вер', 10 => 'жов', 11 => 'лис', 12 => 'гру'
];
// Виведення результатів у таблицю
foreach ($prices_output as $metal => $row) {
if ($row) {
// Отримання номера місяця з дати
$monthNum = date('n', strtotime($row->last_update));
// Заміна англійської назви місяця на українську
$ukrMonth = $ukrMonths[$monthNum];
// Форматування дати
$formattedDate = date('d ', strtotime($row->last_update)) . $ukrMonth . date(' Y', strtotime($row->last_update));
$output .= sprintf(
'<tr><td>%s</td><td class="high-price price-centered">%.2f грн</td><td class="price-centered">%.2f грн</td><td class="price-centered">%.2f грн</td><td class="date-centered">%s</td></tr>',
esc_html($metal), // Назва металу
$row->high_price, // Висока ціна
$row->average_price, // Середня ціна
$row->low_price, // Низька ціна
$formattedDate // Дата оновлення
);
}
}
// Закінчення таблиці
$output .= '</tbody></table>';
return $output; // Повертаємо готову таблицю
}
// Додаємо шорткод
add_shortcode('scrap_metal_prices', 'scrap_metal_prices_shortcode');