$p['status'] === 'pending')); logMessage("Found $pendingCount pending posts"); foreach ($posts as &$post) { // Skip if not pending if ($post['status'] !== 'pending') { continue; } $scheduledTime = strtotime($post['scheduled_time']); logMessage("Post {$post['id']}: scheduled for " . date('Y-m-d H:i:s', $scheduledTime) . " ($scheduledTime)"); if ($scheduledTime > $now) { $diff = $scheduledTime - $now; logMessage(" -> Not yet time (in $diff seconds)"); continue; } logMessage(" -> Time to publish!"); // Prepare text with tags $baseText = $post['text'] ?? ''; $tags = $post['tags'] ?? []; if (!empty($tags)) { $tagsString = implode(' ', array_map(function($t) { return '#' . $t; }, $tags)); $baseText = $baseText ? $baseText . "\n\n" . $tagsString : $tagsString; } // Collect all photo URLs $photoUrls = $post['photos'] ?? []; $uploadedFiles = $post['uploaded_files'] ?? []; foreach ($uploadedFiles as $file) { if (!empty($file['url'])) { $photoUrls[] = $file['url']; } } logMessage(" Photos: " . count($photoUrls)); // Check if cross-promo was enabled for this post $crossPromoEnabled = $post['cross_promo'] ?? false; logMessage(" Cross-promo enabled: " . ($crossPromoEnabled ? 'yes' : 'no')); // Load cross-promo settings if enabled $crossPromoFile = __DIR__ . '/data/cross_promo.json'; $crossPromo = []; if ($crossPromoEnabled && file_exists($crossPromoFile)) { $crossPromo = json_decode(file_get_contents($crossPromoFile), true) ?: []; } $hasCrossPromo = $crossPromoEnabled && (!empty($crossPromo['telegramLink']) || !empty($crossPromo['vkLink'])); // Check which platforms we're posting to $platforms = $post['platforms'] ?? []; $postingToTelegram = false; $postingToVk = false; foreach ($platforms as $p) { $pType = $p['type'] ?? $p; if ($pType === 'telegram') $postingToTelegram = true; if ($pType === 'vk') $postingToVk = true; } // Prepare platform-specific texts with cross-promo $textForTelegram = $baseText; $textForVk = $baseText; if ($hasCrossPromo) { // Add VK link to Telegram posts if (!empty($crossPromo['vkLink']) && $postingToTelegram) { $linkText = $crossPromo['textForTg'] ?? 'Мой канал ВКонтакте'; $textForTelegram .= "\n\n{$linkText}"; logMessage(" Cross-promo: VK link added to TG text"); } // Add Telegram link to VK posts if (!empty($crossPromo['telegramLink']) && $postingToVk) { $linkText = $crossPromo['textForVk'] ?? 'Мой канал в Telegram'; $textForVk .= "\n\n{$linkText}: {$crossPromo['telegramLink']}"; logMessage(" Cross-promo: TG link added to VK text"); } } $results = []; logMessage(" Platforms: " . json_encode($platforms)); logMessage(" TG token set: " . (!empty($config['telegram']['bot_token']) ? 'yes' : 'NO')); logMessage(" VK token set: " . (!empty($config['vk']['access_token']) ? 'yes' : 'NO')); if (empty($platforms)) { logMessage(" WARNING: No platforms specified!"); } foreach ($platforms as $platform) { $type = $platform['type'] ?? $platform; $target = $platform['target'] ?? ''; logMessage(" Processing platform: $type, target: $target"); if ($type === 'telegram') { if (empty($config['telegram']['bot_token'])) { logMessage(" Telegram: SKIPPED - no bot token in config"); continue; } try { $telegram = new TelegramBot($config['telegram']['bot_token']); // Get first channel if no target specified if (empty($target)) { $channels = $telegram->getChannels(); logMessage(" Telegram channels: " . count($channels)); if (!empty($channels)) { $target = $channels[0]['id']; } } if ($target) { logMessage(" Posting to Telegram channel: $target"); $result = $telegram->post($target, $photoUrls, $textForTelegram, 'HTML'); $results['telegram'] = ['success' => true, 'result' => $result]; logMessage(" Telegram: OK"); } else { $results['telegram'] = ['success' => false, 'error' => 'No target channel']; logMessage(" Telegram: No target channel"); } } catch (Exception $e) { $results['telegram'] = ['success' => false, 'error' => $e->getMessage()]; logMessage(" Telegram: ERROR - {$e->getMessage()}"); } } if ($type === 'vk') { if (empty($config['vk']['access_token'])) { logMessage(" VK: SKIPPED - no access token in config"); continue; } try { $vk = new VKAPI($config['vk']['access_token']); // Get first group if no target specified if (empty($target)) { $validation = $vk->validateToken(); if ($validation['valid'] && ($validation['type'] ?? '') === 'community') { $target = $validation['user_id']; } else { $groups = $vk->getGroups(); if (!empty($groups)) { $target = $groups[0]['id']; } } } if ($target) { logMessage(" Posting to VK group: $target"); $result = $vk->post($target, $photoUrls, strip_tags($textForVk)); $results['vk'] = ['success' => true, 'result' => $result]; logMessage(" VK: OK"); } else { $results['vk'] = ['success' => false, 'error' => 'No target group']; logMessage(" VK: No target group"); } } catch (Exception $e) { $results['vk'] = ['success' => false, 'error' => $e->getMessage()]; logMessage(" VK: ERROR - {$e->getMessage()}"); } } } // Update post status $post['status'] = 'published'; $post['published_at'] = date('Y-m-d H:i:s'); $post['results'] = $results; $updated = true; logMessage("Post {$post['id']} marked as published"); } // Save updated posts if ($updated) { file_put_contents($scheduledFile, json_encode($posts, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); logMessage("Posts file updated"); } logMessage("Done\n---");