Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.24% covered (success)
95.24%
20 / 21
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
IndexationPage
95.24% covered (success)
95.24%
20 / 21
75.00% covered (warning)
75.00%
3 / 4
9
0.00% covered (danger)
0.00%
0 / 1
 get
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 save
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
3
 clear
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isValid
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
4.05
1<?php
2/**
3 * IndexationPage Manager (MVP-001, 2026-08-01).
4 *
5 * Client-side storage + retrieval for the operator's indexation page URL.
6 * The URL is stored in WP options and submitted to the server via
7 * POST /v1/indexation-page/register (HMAC-signed).
8 *
9 * Storage: WP option 'swapads_client_indexation_page' (string URL or '').
10 *
11 * @package SwapAds\Client\Indexation
12 *
13 * @since 1.5.7
14 */
15
16declare(strict_types=1);
17
18namespace SwapAds\Client\Indexation;
19
20/**
21 * Class IndexationPage.
22 *
23 * @since 1.5.7
24 */
25final class IndexationPage
26{
27    public const OPTION_KEY = 'swapads_client_indexation_page';
28
29    public const MAX_LENGTH = 512;
30
31    /**
32     * Get the stored indexation page URL, or empty string if not set.
33     *
34     * @return string URL or ''.
35     *
36     * @since 1.5.7
37     */
38    public static function get(): string
39    {
40        return (string) get_option(self::OPTION_KEY, '');
41    }
42
43    /**
44     * Validate + store the indexation page URL locally.
45     *
46     * @param string $url URL to store.
47     *
48     * @return array<string, mixed> Result {success: bool, error?: string, url: string}.
49     *
50     * @since 1.5.7
51     */
52    public static function save(string $url): array
53    {
54        $url = trim($url);
55        if ($url === '') {
56            // Allow clearing the value.
57            update_option(self::OPTION_KEY, '');
58            return ['success' => true, 'url' => ''];
59        }
60
61        if (!self::isValid($url)) {
62            return [
63                'success' => false,
64                'error'   => 'Indexation page URL must be a valid http(s) URL.',
65                'url'     => $url,
66            ];
67        }
68
69        update_option(self::OPTION_KEY, $url);
70        return ['success' => true, 'url' => $url];
71    }
72
73    /**
74     * Delete the stored URL (empty string).
75     *
76     * @return bool True if option was deleted/updated.
77     *
78     * @since 1.5.7
79     */
80    public static function clear(): bool
81    {
82        return (bool) update_option(self::OPTION_KEY, '');
83    }
84
85    /**
86     * Validate that the URL is well-formed.
87     *
88     * @param string $url URL.
89     *
90     * @return bool True if valid.
91     *
92     * @since 1.5.7
93     */
94    public static function isValid(string $url): bool
95    {
96        if (strlen($url) > self::MAX_LENGTH) {
97            return false;
98        }
99        if (!preg_match('#^https?://#i', $url)) {
100            return false;
101        }
102        if (!filter_var($url, FILTER_VALIDATE_URL)) {
103            return false;
104        }
105        return true;
106    }
107}