\n");
fwrite($fp, "\n");
// مهم: برای جلوگیری از OFFSET کندی شدید در MySQL، بهتره از "ID pagination" استفاده کنیم.
// ولی چون ساخت 500k معمولاً خارج از درخواست و با batch بزرگ انجام میشود، این نسخه هم قابل قبول است.
// نسخه فوقالعادهتر (keyset) را اگر خواستید مینویسم.
$sqlBase = "
SELECT
p.ID,
p.post_title,
p.post_name,
pm_price.meta_value AS price,
pm_stock.meta_value AS stock,
pm_thumb.meta_value AS thumb
FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->postmeta} pm_price
ON pm_price.post_id = p.ID AND pm_price.meta_key = '_price'
LEFT JOIN {$wpdb->postmeta} pm_stock
ON pm_stock.post_id = p.ID AND pm_stock.meta_key = '_stock_status'
LEFT JOIN {$wpdb->postmeta} pm_thumb
ON pm_thumb.post_id = p.ID AND pm_thumb.meta_key = '_thumbnail_id'
WHERE p.post_type='product' AND p.post_status='publish'
ORDER BY p.ID ASC
LIMIT %d OFFSET %d
";
while (true) {
$sql = $wpdb->prepare($sqlBase, $batch, $offset);
$rows = $wpdb->get_results($sql);
if (!$rows) break;
foreach ($rows as $row) {
// stock
if ($row->stock !== 'instock') continue;
$price = (int) $row->price;
if ($price <= 0) continue;
$title = tr_clean($row->post_title);
$url = $site . '/product/' . $row->post_name . '/';
// thumb: مستقیم wp_get_attachment_url برای هر ردیف میتواند کند باشد.
// GOD MODE واقعی این است که thumbnail URL را با join بر اساس _wp_attached_file داشته باشیم یا کش کنیم.
// این نسخه با حداقلسازی بار میسازد (thumb خالی را پیشفرض میگذارد).
$img = $row->thumb ? wp_get_attachment_url((int)$row->thumb) : ($site.'/wp-content/uploads/default-product.jpg');
// خروجی XML
fwrite($fp, "\n");
fwrite($fp, " {$row->ID}\n");
fwrite($fp, " \n");
fwrite($fp, " {$price}\n");
fwrite($fp, " \n");
fwrite($fp, " \n");
fwrite($fp, " instock\n");
fwrite($fp, "\n");
}
$offset += $batch;
}
fwrite($fp, "");
fclose($fp);
// جایگزینی اتمیک
if (file_exists($tmp_file) && filesize($tmp_file) > 500) {
@rename($tmp_file, $cache_file);
// gzip
$data = file_get_contents($cache_file);
if ($data !== false) {
file_put_contents($gzip_file, gzencode($data, 9));
}
}
flock($lockFp, LOCK_UN);
fclose($lockFp);
@unlink($lock_file);
php
define('WP_USE_THEMES', false);
require('wp-load.php');
$cache_file = __DIR__ . '/torob_god.xml';
$gzip_file = __DIR__ . '/torob_god.xml.gz';
$ttl = 1800; // 30m
header("Content-Type: text/xml; charset=UTF-8");
if (file_exists($cache_file) && (time() - filemtime($cache_file) < $ttl)) {
// اگر gzip هست و کلاینت پشتیبانی میکند
if (!empty($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false && file_exists($gzip_file)) {
header('Content-Encoding: gzip');
readfile($gzip_file);
exit;
}
readfile($cache_file);
exit;
}
// fallback: اگر cache خراب/وجود نداشت، همان لحظه try rebuild
require __DIR__ . '/torob-god-build.php';
exit;