$limits Saved settings over the defaults. */ return Limits::normalize( apply_filters( 'fitzaro/limits', array_merge( Limits::DEFAULTS, (array) get_option( self::OPTION_LIMITS, array() ) ) ) ); } /** * Seconds to keep photos, results and request rows (see Cleanup::DEFAULTS). * * @return array{uploads: int, results: int, rows: int} */ public static function retention(): array { /** * Filters how long data is kept, in seconds. Keys: uploads, results, rows. Values below the * safe minimums are raised to them. * * @since 1.0.0 * * @param array $retention Retention in seconds. */ return Cleanup::retention( apply_filters( 'fitzaro/retention', Cleanup::DEFAULTS ) ); } /** * OpenAI model for new try-ons. */ public static function openai_model(): string { $model = get_option( self::OPTION_MODEL, OpenAiProvider::DEFAULT_MODEL ); return is_string( $model ) && in_array( $model, OpenAiProvider::MODELS, true ) ? $model : OpenAiProvider::DEFAULT_MODEL; } /** * Whether the storefront offers try-on at all (the owner's master switch). */ public static function enabled(): bool { return 'no' !== get_option( self::OPTION_ENABLED, 'yes' ); } /** * Product types the owner offers try-on for. All of them by default. * * @return string[] */ public static function enabled_types(): array { $all = array( Prompt\ProductType::TOP, Prompt\ProductType::DRESS, Prompt\ProductType::EYEWEAR ); $saved = get_option( self::OPTION_TYPES, $all ); return array_values( array_intersect( $all, is_array( $saved ) ? $saved : $all ) ); } }