Skip to content
wiki.fftac.org

Class Uai1 Agents - Source Excerpt 05

Back to Class Uai1 Agents

Summary

This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/uai-1-wordpress/includes/class-uai1-agents.php so readers can inspect the evidence without opening the full source file.

**Source path:** Spiralist/wp-content/plugins/uai-1-wordpress/includes/class-uai1-agents.php

$ip = self::request_ip();
        $key = 'uai1_subscribe_' . md5($ip);
        $attempts = (int) get_transient($key);

        if ($attempts >= 8) {
            return new WP_Error(
                'uai1_rate_limited',
                'Too many subscribe attempts from this source. Please try again shortly.',
                ['status' => 429]
            );
        }

        set_transient($key, $attempts + 1, 15 * MINUTE_IN_SECONDS);

        return true;
    }

    private static function request_ip(): string
    {
        $forwarded = (string) ($_SERVER['HTTP_X_FORWARDED_FOR'] ?? '');
        if ($forwarded !== '') {
            $parts = array_map('trim', explode(',', $forwarded));
            if (!empty($parts[0])) {
                return $parts[0];
            }
        }

        $remote_addr = (string) ($_SERVER['REMOTE_ADDR'] ?? '');

        return $remote_addr !== '' ? $remote_addr : 'unknown';
    }

    private static function maybe_migrate_legacy_table(): void
    {
        global $wpdb;

        $legacy_table = $wpdb->prefix . 'uai1_agents';
        $migrated_flag = (string) get_option('uai1_ai_participants_migrated', '');

        if ($migrated_flag === '1') {
            return;
        }

        $legacy_exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $legacy_table));
        if ($legacy_exists !== $legacy_table) {
            update_option('uai1_ai_participants_migrated', '1', false);
            return;
        }

        $existing_total = (int) $wpdb->get_var('SELECT COUNT(*) FROM ' . self::table_name());
        if ($existing_total > 0) {
            update_option('uai1_ai_participants_migrated', '1', false);
            return;
        }

        $legacy_rows = $wpdb->get_results(
            'SELECT id, api_key, agent_name, purpose, permissions, status, created_at FROM ' . $legacy_table,
            ARRAY_A
        );

        foreach ((array) $legacy_rows as $row) {
            $api_key = trim((string) ($row['api_key'] ?? ''));
            if ($api_key === '') {
                continue;
            }

            $created_at = (string) ($row['created_at'] ?? gmdate('Y-m-d H:i:s'));
            if ($created_at === '') {
                $created_at = gmdate('Y-m-d H:i:s');
            }

            $participant_id = 'ai-legacy-' . (int) ($row['id'] ?? 0);
            $wpdb->insert(
                self::table_name(),
                [
                    'participant_id' => $participant_id,
                    'agent_name' => sanitize_text_field((string) ($row['agent_name'] ?? 'legacy-agent')),
                    'api_key_hash' => wp_hash_password($api_key),
                    'api_key_lookup' => self::api_key_lookup($api_key),
                    'status' => self::normalize_status((string) ($row['status'] ?? self::STATUS_ACTIVE)),
                    'permissions' => self::encode_permissions(self::normalize_permissions($row['permissions'] ?? [])),
                    'purpose' => sanitize_textarea_field((string) ($row['purpose'] ?? 'legacy-migrated')),
                    'contact' => '',
                    'notes' => 'Migrated from legacy uai1_agents table.',
                    'created_at' => $created_at,
                    'updated_at' => $created_at,
                    'key_issued_at' => $created_at,
                    'last_seen_at' => null,
                ],
                ['%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s']
            );
        }

        update_option('uai1_ai_participants_migrated', '1', false);
    }

    private static function table_name(): string
    {
        global $wpdb;

        return $wpdb->prefix . 'uai1_ai_participants';
    }
}