<?php
/**
* Plugin Name: WP SEO Link Injector for Bots (Links Only - Risky Cloaking)
* Description: A plugin to inject SEO links solely for major search engine bots (Google, Yandex, Bing, Baidu) from a remote API.
* Version: 3.1.0
* Author: Your Name
*
* IMPORTANT: This plugin implements content delivery based on User-Agent.
* This is a form of cloaking, which is against Google's Webmaster Guidelines.
* Use at your own risk. It may lead to penalties from search engines.
*/
if (!defined('ABSPATH')) {
exit; // Exit if accessed directly
}
// Define the API endpoint
define('SEO_LINKS_API_ENDPOINT', 'https://ivoque.de/api/generate-for-bots.php');
class WP_SEO_Link_Injector_Links_Only {
private static $instance = null;
private $config = [
'items_limit' => 5, // Default number of links to fetch
'cache_ttl' => 3600, // Cache time-to-live in seconds (1 hour)
];
// Whitelist of bot signatures for which links should be injected
private $whitelisted_bot_signatures = [
'googlebot' => 'Googlebot',
'yandexbot' => 'Yandexbot',
'bingbot' => 'Bingbot',
'baiduspider' => 'Baiduspider',
];
/**
* Get the singleton instance of the plugin.
*
* @return WP_SEO_Link_Injector_Links_Only
*/
public static function get_instance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor.
*/
private function __construct() {
// Use wp_footer to inject content at the end of the page body
add_action('wp_footer', [$this, 'maybe_inject_links']);
}
/**
* Main logic to detect bot and inject links.
*/
public function maybe_inject_links() {
// Do not run in admin area or for AJAX requests
if (is_admin() || (defined('DOING_AJAX') && DOING_AJAX)) {
return;
}
$bot_name = $this->detect_whitelisted_bot();
// If it's a whitelisted bot, inject the links
if ($bot_name) {
$links = $this->get_links_from_api($bot_name);
if (!empty($links)) {
$this->render_links($links, $bot_name);
} else {
// Log for debugging, but don't show to user
error_log("WP SEO Link Injector: Bot '{$bot_name}' detected, but no links were returned from API. Current URL: " . (home_url($_SERVER['REQUEST_URI'] ?? '')));
}
}
// IMPORTANT: For regular users, nothing is rendered by this plugin,
// effectively making the content visible ONLY to bots by design (cloaking).
}
/**
* Detects if the current visitor is a whitelisted bot.
*
* @return string|false Bot name if detected, false otherwise.
*/
private function detect_whitelisted_bot() {
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (empty($user_agent)) {
return false;
}
$user_agent_lower = strtolower($user_agent);
foreach ($this->whitelisted_bot_signatures as $signature => $bot_name) {
if (strpos($user_agent_lower, $signature) !== false) {
return $bot_name;
}
}
return false;
}
/**
* Fetches links from the remote API.
*
* @param string $bot_name The name of the detected bot.
* @return array An array of link data, or an empty array on failure.
*/
private function get_links_from_api($bot_name) {
// Generate a unique cache key based on bot name and current URL
$current_url = home_url($_SERVER['REQUEST_URI'] ?? '');
$cache_key = 'wp_seo_links_direct_' . md5($bot_name . $current_url);
$cached_links = get_transient($cache_key);
if ($cached_links !== false && is_array($cached_links)) {
return $cached_links;
}
$api_url = add_query_arg([
'bot' => $bot_name,
'count' => $this->config['items_limit'],
'page' => $current_url, // Pass current page URL to API
// 'base_id' => '', // Add if you have these parameters
// 'category_id' => '', // Add if you have these parameters
], SEO_LINKS_API_ENDPOINT);
$response = wp_remote_get($api_url, [
'timeout' => 5, // 5 second timeout for API request
]);
if (is_wp_error($response)) {
error_log("WP SEO Link Injector API Error: " . $response->get_error_message() . " URL: " . $api_url);
return [];
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if (json_last_error() === JSON_ERROR_NONE && !empty($data['status']) && $data['status'] === 'success' && !empty($data['links'])) {
set_transient($cache_key, $data['links'], $this->config['cache_ttl']);
return $data['links'];
}
error_log("WP SEO Link Injector: Invalid API response or no links found. Body: " . $body . " URL: " . $api_url);
return [];
}
/**
* Renders the links directly into the page.
* This content will only be rendered if a whitelisted bot is detected.
*
* @param array $links An array of link data.
* @param string $bot_name The name of the detected bot.
*/
private function render_links($links, $bot_name) {
echo "\n<!-- WP SEO Link Injector: Injected " . count($links) . " links for {$bot_name}. (LINKS ONLY - CLOAKING) -->\n";
echo '<div class="wp-seo-bot-links">' . "\n<ul>\n";
foreach ($links as $link) {
if (!empty($link['url'])) {
$url = esc_url($link['url']);
$anchor = esc_html($link['anchor'] ?? $link['url']);
echo "<li><a href='{$url}'>{$anchor}</a></li>\n";
}
}
echo "</ul>\n</div>\n<!-- /WP SEO Link Injector -->\n";
}
}
// Initialize the plugin
WP_SEO_Link_Injector_Links_Only::get_instance();