class-capabilities.php
5 months ago
class-plugin-settings.php
5 months ago
class-settings.php
5 months ago
class-settings.php
316 lines
| 1 | <?php |
| 2 | |
| 3 | namespace SearchRegex\Plugin; |
| 4 | |
| 5 | class Settings extends Plugin_Settings { |
| 6 | /** @var string */ |
| 7 | const OPTION_NAME = 'searchregex_options'; |
| 8 | |
| 9 | /** @var int */ |
| 10 | const API_JSON = 0; |
| 11 | |
| 12 | /** @var int */ |
| 13 | const API_JSON_INDEX = 1; |
| 14 | |
| 15 | /** @var int */ |
| 16 | const API_JSON_RELATIVE = 3; |
| 17 | |
| 18 | /** |
| 19 | * Initialize the object |
| 20 | * |
| 21 | * @return Settings |
| 22 | */ |
| 23 | public static function init() { |
| 24 | if ( is_null( self::$instance ) ) { |
| 25 | // @phpstan-ignore new.static |
| 26 | self::$instance = new static(); |
| 27 | } |
| 28 | |
| 29 | return self::$instance; |
| 30 | } |
| 31 | |
| 32 | /** |
| 33 | * @return string |
| 34 | */ |
| 35 | protected function get_setting_name() { |
| 36 | return self::OPTION_NAME; |
| 37 | } |
| 38 | |
| 39 | /** |
| 40 | * @return array<string, mixed> |
| 41 | */ |
| 42 | protected function load() { |
| 43 | return \apply_filters( 'searchregex_load_options', parent::load() ); |
| 44 | } |
| 45 | |
| 46 | /** |
| 47 | * @param array<string, mixed> $settings |
| 48 | * @return array<string, mixed> |
| 49 | */ |
| 50 | protected function get_save_data( array $settings ) { |
| 51 | return \apply_filters( 'searchregex_save_options', $settings ); |
| 52 | } |
| 53 | |
| 54 | /** |
| 55 | * Get default Search Regex options |
| 56 | * |
| 57 | * @return array<string, mixed> |
| 58 | */ |
| 59 | protected function get_defaults() { |
| 60 | $defaults = [ |
| 61 | 'support' => false, |
| 62 | 'rest_api' => self::API_JSON, |
| 63 | // Legacy option kept for backwards compatibility. New installs should |
| 64 | // prefer startupMode/startupPreset instead. |
| 65 | 'defaultPreset' => 0, |
| 66 | // Startup behaviour for the UI. "simple" is the default for new |
| 67 | // installs. Existing installs are migrated to "advanced" in __construct. |
| 68 | 'startupMode' => 'simple', |
| 69 | // When startupMode is "preset" this contains the preset ID. |
| 70 | 'startupPreset' => '', |
| 71 | 'update_notice' => 0, |
| 72 | ]; |
| 73 | |
| 74 | return \apply_filters( 'searchregex_default_options', $defaults ); |
| 75 | } |
| 76 | |
| 77 | /** |
| 78 | * Settings constructor. |
| 79 | * |
| 80 | * Ensures new startup options are initialised and migrates any legacy |
| 81 | * default preset configuration into the new structure. First-time installs |
| 82 | * default to "simple" mode, while existing installs preserve "advanced" mode |
| 83 | * unless the user has explicitly saved a preference. |
| 84 | * |
| 85 | * @return void |
| 86 | */ |
| 87 | public function __construct() { |
| 88 | parent::__construct(); |
| 89 | |
| 90 | $saved_settings = $this->load(); |
| 91 | |
| 92 | // Check if this is an existing installation by looking for any saved settings. |
| 93 | // Empty array means first-time install (will use "simple" default). |
| 94 | $is_existing_install = count( $saved_settings ) > 0; |
| 95 | |
| 96 | // If startupMode has not been initialised yet, handle migration. |
| 97 | if ( ! isset( $this->settings['startupMode'] ) ) { |
| 98 | // For existing installs, migrate from legacy defaultPreset. |
| 99 | if ( $is_existing_install ) { |
| 100 | $legacy_default = $this->get( 'defaultPreset', 0 ); |
| 101 | |
| 102 | if ( $legacy_default !== false && $legacy_default !== 0 && $legacy_default !== '0' && $legacy_default !== '' ) { |
| 103 | // A preset was previously selected as the default. |
| 104 | $this->settings['startupMode'] = 'preset'; |
| 105 | if ( is_string( $legacy_default ) ) { |
| 106 | $this->settings['startupPreset'] = $legacy_default; |
| 107 | } else { |
| 108 | // @phpstan-ignore cast.string |
| 109 | $this->settings['startupPreset'] = (string) $legacy_default; |
| 110 | } |
| 111 | } else { |
| 112 | // No default preset configured – previously this meant the |
| 113 | // standard (advanced) UI. Keep that behaviour for existing users. |
| 114 | $this->settings['startupMode'] = 'advanced'; |
| 115 | $this->settings['startupPreset'] = ''; |
| 116 | } |
| 117 | } |
| 118 | // For new installs, startupMode will be "simple" from get_defaults(). |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | /** |
| 123 | * @param int $rest_api |
| 124 | * @return void |
| 125 | */ |
| 126 | public function set_rest_api( $rest_api ) { |
| 127 | $rest_api = intval( $rest_api, 10 ); |
| 128 | |
| 129 | if ( in_array( $rest_api, [ 0, 1, 2, 3, 4 ], true ) ) { |
| 130 | $this->settings['rest_api'] = $rest_api; |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | /** |
| 135 | * @param bool $is_supported |
| 136 | * @return void |
| 137 | */ |
| 138 | public function set_is_supported( $is_supported ) { |
| 139 | $this->settings['support'] = $is_supported ? true : false; |
| 140 | } |
| 141 | |
| 142 | /** |
| 143 | * @return void |
| 144 | */ |
| 145 | public function set_latest_version() { |
| 146 | $major_version = explode( '-', SEARCHREGEX_VERSION )[0]; // Remove any beta suffix |
| 147 | $major_version = implode( '.', array_slice( explode( '.', SEARCHREGEX_VERSION ), 0, 2 ) ); |
| 148 | |
| 149 | $this->settings['update_notice'] = $major_version; |
| 150 | } |
| 151 | |
| 152 | /** |
| 153 | * @param string $preset_id |
| 154 | * @return void |
| 155 | */ |
| 156 | public function set_default_preset( $preset_id ) { |
| 157 | // Keep legacy behaviour for callers that still use this method, but |
| 158 | // avoid accepting arbitrary values. |
| 159 | $cleaned = preg_replace( '/[^A-Fa-f0-9]*/', '', $preset_id ); |
| 160 | $this->settings['defaultPreset'] = $cleaned !== null ? $cleaned : ''; |
| 161 | } |
| 162 | |
| 163 | /** |
| 164 | * Set startup mode. |
| 165 | * |
| 166 | * @param string $mode Startup mode (simple, advanced, preset). |
| 167 | * @return void |
| 168 | */ |
| 169 | public function set_startup_mode( $mode ) { |
| 170 | $mode = (string) $mode; |
| 171 | |
| 172 | if ( ! in_array( $mode, [ 'simple', 'advanced', 'preset' ], true ) ) { |
| 173 | return; |
| 174 | } |
| 175 | |
| 176 | $this->settings['startupMode'] = $mode; |
| 177 | } |
| 178 | |
| 179 | /** |
| 180 | * Set startup preset id. |
| 181 | * |
| 182 | * @param string $preset_id Preset ID to use when startupMode is "preset". |
| 183 | * @return void |
| 184 | */ |
| 185 | public function set_startup_preset( $preset_id ) { |
| 186 | $this->settings['startupPreset'] = (string) $preset_id; |
| 187 | } |
| 188 | |
| 189 | /** |
| 190 | * Get startup mode. |
| 191 | * |
| 192 | * @return string |
| 193 | */ |
| 194 | public function get_startup_mode() { |
| 195 | $mode = $this->get( 'startupMode', 'advanced' ); |
| 196 | |
| 197 | if ( ! in_array( $mode, [ 'simple', 'advanced', 'preset' ], true ) ) { |
| 198 | return 'advanced'; |
| 199 | } |
| 200 | |
| 201 | return $mode; |
| 202 | } |
| 203 | |
| 204 | /** |
| 205 | * Get startup preset id. |
| 206 | * |
| 207 | * @return string |
| 208 | */ |
| 209 | public function get_startup_preset() { |
| 210 | $preset = $this->get( 'startupPreset', '' ); |
| 211 | if ( is_string( $preset ) ) { |
| 212 | return $preset; |
| 213 | } |
| 214 | // @phpstan-ignore cast.string |
| 215 | return (string) $preset; |
| 216 | } |
| 217 | |
| 218 | /** |
| 219 | * @param string $major_version |
| 220 | * @return bool |
| 221 | */ |
| 222 | public function is_new_version( $major_version ) { |
| 223 | $update_notice = $this->get( 'update_notice', '0' ); |
| 224 | if ( ! is_string( $update_notice ) ) { |
| 225 | // @phpstan-ignore cast.string |
| 226 | $update_notice = (string) $update_notice; |
| 227 | } |
| 228 | return version_compare( $update_notice, $major_version ) < 0; |
| 229 | } |
| 230 | |
| 231 | /** |
| 232 | * @return bool |
| 233 | */ |
| 234 | public function is_supported() { |
| 235 | return $this->get( 'support' ) ? true : false; |
| 236 | } |
| 237 | |
| 238 | /** |
| 239 | * @param int|false $type |
| 240 | * @return int |
| 241 | */ |
| 242 | public function get_rest_api( $type = false ) { |
| 243 | if ( $type === false ) { |
| 244 | $type = $this->get( 'rest_api' ); |
| 245 | } |
| 246 | |
| 247 | if ( is_int( $type ) ) { |
| 248 | return $type; |
| 249 | } |
| 250 | // @phpstan-ignore cast.int |
| 251 | return (int) $type; |
| 252 | } |
| 253 | |
| 254 | /** |
| 255 | * Get the configured REST API |
| 256 | * |
| 257 | * @param int|false $type Type of API. |
| 258 | * @return string API URL |
| 259 | */ |
| 260 | public function get_rest_api_url( $type = false ) { |
| 261 | $type = $this->get_rest_api( $type ); |
| 262 | $url = \get_rest_url(); // API_JSON |
| 263 | |
| 264 | if ( $type === self::API_JSON_INDEX ) { |
| 265 | $url = \home_url( '/index.php?rest_route=/' ); |
| 266 | } elseif ( $type === self::API_JSON_RELATIVE ) { |
| 267 | $relative = \wp_parse_url( $url, PHP_URL_PATH ); |
| 268 | |
| 269 | if ( $relative ) { |
| 270 | $url = $relative; |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | return $url; |
| 275 | } |
| 276 | |
| 277 | /** |
| 278 | * @return array<int, string> |
| 279 | */ |
| 280 | public function get_available_rest_api() { |
| 281 | return [ |
| 282 | self::API_JSON => $this->get_rest_api_url( self::API_JSON ), |
| 283 | self::API_JSON_INDEX => $this->get_rest_api_url( self::API_JSON_INDEX ), |
| 284 | self::API_JSON_RELATIVE => $this->get_rest_api_url( self::API_JSON_RELATIVE ), |
| 285 | ]; |
| 286 | } |
| 287 | |
| 288 | /** |
| 289 | * @return string|null |
| 290 | */ |
| 291 | public function get_default_preset() { |
| 292 | $preset = $this->get( 'defaultPreset' ); |
| 293 | if ( $preset === false || $preset === null ) { |
| 294 | return null; |
| 295 | } |
| 296 | if ( is_string( $preset ) ) { |
| 297 | return $preset; |
| 298 | } |
| 299 | // @phpstan-ignore cast.string |
| 300 | return (string) $preset; |
| 301 | } |
| 302 | |
| 303 | /** |
| 304 | * Can we save data to the database? Useful for disabling saves during debugging |
| 305 | * |
| 306 | * @return boolean |
| 307 | */ |
| 308 | public function can_save() { |
| 309 | if ( defined( 'SEARCHREGEX_DEBUG' ) && SEARCHREGEX_DEBUG ) { |
| 310 | return false; |
| 311 | } |
| 312 | |
| 313 | return true; |
| 314 | } |
| 315 | } |
| 316 |