'–', 'title_home' => '%sitename% %sep% %tagline%', 'title_post' => '%title% %sep% %sitename%', 'title_page' => '%title% %sep% %sitename%', 'title_term' => '%term% %sep% %sitename%', 'title_author' => '%author% %sep% %sitename%', 'title_archive' => '%archive% %sep% %sitename%', 'title_search' => 'Search results for "%searchphrase%" %sep% %sitename%', 'title_404' => 'Page not found %sep% %sitename%', 'home_description' => '', 'description_len' => 155, // Legacy + extra meta ---------------------------------------------------------------- 'meta_keywords' => 1, 'meta_author' => 1, 'meta_language' => 1, 'meta_copyright' => 1, 'meta_legacy' => 1, // revisit-after, rating, distribution, resource-type, format-detection 'dublin_core' => 1, 'geo_meta' => 1, 'hreflang' => 1, 'cleanup_head' => 1, // generator, RSD, wlwmanifest, shortlink // Social ------------------------------------------------------------------------------ 'og' => 1, 'twitter_card' => 'summary_large_image', 'twitter_site' => '', 'fb_app_id' => '', 'default_image' => '', // Robots / indexing ------------------------------------------------------------------ 'noindex_search' => 1, 'noindex_date' => 1, 'noindex_author' => 'auto', // auto = only when the site has one author 'attachment_redirect' => 1, 'robots_max' => 1, // max-image-preview:large, max-snippet:-1, max-video-preview:-1 'feeds_noindex' => 1, 'robots_txt_extras'=> 1, 'ai_policy' => 'allow', // allow | block_training // Business / schema ------------------------------------------------------------------ 'org_type' => 'Organization', 'org_name' => '', 'org_legal_name' => '', 'org_description' => '', 'org_knows_about' => '', // topics, comma separated 'org_services' => '', // one service per line 'org_logo' => '', 'org_phone' => '', 'org_email' => '', 'org_street' => '', 'org_city' => '', 'org_region' => '', 'org_postcode' => '', 'org_country' => 'GB', 'org_lat' => '', 'org_lng' => '', 'org_price_range' => '', 'org_hours' => '', // one per line, e.g. "Mo-Fr 09:00-17:30" 'org_area' => '', // areas served, comma separated 'org_profiles' => '', // social profile URLs, one per line 'article_type' => 'BlogPosting', 'breadcrumb_sep' => '›', // Verification ------------------------------------------------------------------------- 'v_google' => '', 'v_bing' => '', 'v_yandex' => '', 'v_baidu' => '', 'v_pinterest' => '', 'v_facebook' => '', // Sitemap / discovery ------------------------------------------------------------------ 'sitemap' => 1, 'sitemap_images' => 1, 'sitemap_exclude_types' => array(), 'indexnow' => SXSEO_Edition::is_pro() ? 1 : 0, // opt-in: sends each published URL to api.indexnow.org (see readme "External services") 'indexnow_key' => '', 'llms_txt' => 1, // Redirects / 404 ------------------------------------------------------------------------ 'auto_redirects' => 1, 'smart_404' => 1, 'log_404' => 1, // Content --------------------------------------------------------------------------------- 'auto_alt' => 1, // Updates --------------------------------------------------------------------------------- 'auto_update' => 1, ); } public static function hook() { add_action( 'update_option_' . self::OPTION, array( __CLASS__, 'flush_cache' ) ); } public static function flush_cache() { self::$cache = null; } public static function all() { if ( null === self::$cache ) { $saved = get_option( self::OPTION, array() ); self::$cache = array_merge( self::defaults(), is_array( $saved ) ? $saved : array() ); } return self::$cache; } public static function get( $key, $default = null ) { $all = self::all(); return array_key_exists( $key, $all ) ? $all[ $key ] : $default; } public static function ensure_defaults() { $saved = get_option( self::OPTION, null ); if ( ! is_array( $saved ) ) { // Seed the business name and logo from what the site already knows. $seed = array( 'org_name' => get_bloginfo( 'name' ) ); $logo = get_theme_mod( 'custom_logo' ); if ( $logo ) { $url = wp_get_attachment_image_url( $logo, 'full' ); if ( $url ) { $seed['org_logo'] = $url; } } add_option( self::OPTION, $seed, '', 'yes' ); } if ( '' === (string) self::get( 'indexnow_key' ) ) { $all = get_option( self::OPTION, array() ); $all['indexnow_key'] = wp_generate_password( 32, false, false ); update_option( self::OPTION, $all ); } self::flush_cache(); } public static function save( array $in ) { $def = self::defaults(); $cur = self::all(); $out = $cur; foreach ( $def as $k => $d ) { if ( ! array_key_exists( $k, $in ) ) { // Unticked checkboxes are absent from a form post; only reset flags that were on the submitted tab. continue; } $v = $in[ $k ]; if ( is_array( $d ) ) { $out[ $k ] = array_values( array_filter( array_map( 'sanitize_key', (array) $v ) ) ); } elseif ( in_array( $k, array( 'org_hours', 'org_profiles', 'org_services' ), true ) ) { $out[ $k ] = implode( "\n", array_filter( array_map( 'trim', preg_split( '/\r\n|\r|\n/', (string) $v ) ) ) ); } elseif ( in_array( $k, array( 'default_image', 'org_logo' ), true ) ) { $out[ $k ] = esc_url_raw( (string) $v ); } elseif ( is_int( $d ) && ! in_array( $k, array( 'description_len' ), true ) ) { $out[ $k ] = $v ? 1 : 0; } elseif ( 'description_len' === $k ) { $out[ $k ] = max( 100, min( 320, (int) $v ) ); } else { $out[ $k ] = sanitize_text_field( (string) $v ); } } update_option( self::OPTION, $out ); self::flush_cache(); SXSEO_Sitemap::purge(); } }