| @@ -1,0 +1,249 @@ | ||
| 1 | +<?php | |
| 2 | +namespace ABlocks\Admin\Settings; | |
| 3 | + | |
| 4 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 5 | + exit; | |
| 6 | +} | |
| 7 | + | |
| 8 | +use ABlocks\Controls\Typography; | |
| 9 | +use ABlocks\Controls\Range; | |
| 10 | + | |
| 11 | +class Base { | |
| 12 | + public static function get_saved_data() { | |
| 13 | + $settings = get_option( ABLOCKS_SETTINGS_NAME ); | |
| 14 | + if ( $settings ) { | |
| 15 | + return json_decode( $settings, true ); | |
| 16 | + } | |
| 17 | + return []; | |
| 18 | + } | |
| 19 | + public static function get_default_data() { | |
| 20 | + return apply_filters('ablocks/admin/settings/base_default_data', [ | |
| 21 | + // global style | |
| 22 | + 'default_container_width' => 1140, | |
| 23 | + 'container_padding' => 10, | |
| 24 | + 'container_element_gap' => 20, | |
| 25 | + // Responsive breakpoint widths (px). Consumed by every CSS generator | |
| 26 | + // and the block editor; see Helper::get_breakpoints(). | |
| 27 | + 'breakpoint_tablet' => 800, | |
| 28 | + 'breakpoint_mobile' => 480, | |
| 29 | + // How breakpoint queries relate: 'cascade' (max-width envelopes — a | |
| 30 | + // Tablet value also applies on Mobile) or 'strict' (exclusive bands). | |
| 31 | + // See Helper::get_breakpoint_mode(). | |
| 32 | + 'breakpoint_mode' => 'cascade', | |
| 33 | + // User-registered extra breakpoints: [ { key, label, width } ]. | |
| 34 | + 'breakpoint_custom' => [], | |
| 35 | + 'enabled_assets_file_generation' => false, | |
| 36 | + 'enabled_block_copy_paste_style' => true, | |
| 37 | + // Design system lock: authors may only use the global typography / | |
| 38 | + // colour presets, so nobody can hand-pick a one-off value by mistake. | |
| 39 | + 'lock_global_typography' => false, | |
| 40 | + // Escalates the typography lock from 'no picking a typeface' to 'no | |
| 41 | + // custom typography at all'. Off by default: adjusting a size is normal | |
| 42 | + // design work, picking a stray typeface is the mistake. | |
| 43 | + 'lock_global_typography_strict' => false, | |
| 44 | + 'lock_global_colors' => false, | |
| 45 | + 'enabled_load_google_font_locally' => false, | |
| 46 | + 'enabled_only_selected_fonts' => false, | |
| 47 | + 'selected_fonts' => [], | |
| 48 | + // Emit a metric-adjusted local fallback face per font, so text does not | |
| 49 | + // reflow when the web font finishes loading (CLS). | |
| 50 | + 'font_metric_fallback' => true, | |
| 51 | + // Performance Suite — platform optimizations (opt-in; default off so | |
| 52 | + // existing sites are unchanged until the user enables them). | |
| 53 | + 'perf_disable_emojis' => false, | |
| 54 | + 'perf_disable_embeds' => false, | |
| 55 | + 'perf_disable_dashicons' => false, | |
| 56 | + 'perf_disable_jquery_migrate' => false, | |
| 57 | + 'perf_control_heartbeat' => false, | |
| 58 | + 'perf_heartbeat_frequency' => 60, | |
| 59 | + // Performance Suite — delay JS until interaction. | |
| 60 | + 'perf_delay_js' => false, | |
| 61 | + 'perf_delay_js_timeout' => 5000, | |
| 62 | + // Performance Suite — image loading (safe: on by default). | |
| 63 | + 'perf_lazy_images' => true, | |
| 64 | + 'perf_lcp_eager_count' => 1, | |
| 65 | + 'perf_image_dimensions' => true, | |
| 66 | + 'perf_responsive_images' => true, | |
| 67 | + 'perf_preload_lcp' => true, | |
| 68 | + 'perf_touch_targets' => false, | |
| 69 | + // Performance Suite — inline small page CSS (safe: on by default). | |
| 70 | + 'perf_inline_css' => true, | |
| 71 | + 'perf_async_css' => false, | |
| 72 | + 'perf_critical_css' => false, | |
| 73 | + 'perf_defer_js' => false, | |
| 74 | + // Editor — turn a document pasted from Google Docs into aBlocks blocks | |
| 75 | + // and take its images into the media library as WebP. | |
| 76 | + 'paste_google_docs' => true, | |
| 77 | + 'paste_convert_webp' => true, | |
| 78 | + 'paste_webp_quality' => 92, | |
| 79 | + // Performance Suite — full-page HTML cache. Off by default: unlike | |
| 80 | + // the toggles above it changes what every visitor receives, so it | |
| 81 | + // needs a deliberate decision rather than inheriting a default. | |
| 82 | + // See docs/PAGE-CACHE-PLAN.md. | |
| 83 | + 'perf_page_cache' => false, | |
| 84 | + // 'all' | 'ablocks_only' | |
| 85 | + 'perf_page_cache_scope' => 'all', | |
| 86 | + // Hours; 0 = keep until something invalidates it. | |
| 87 | + 'perf_page_cache_ttl' => 0, | |
| 88 | + 'perf_page_cache_gzip' => true, | |
| 89 | + 'perf_page_cache_prewarm' => true, | |
| 90 | + 'perf_page_cache_mobile_variant' => false, | |
| 91 | + // Empty allowlist means any query string bypasses the cache, so | |
| 92 | + // ?utm_source=x can never overwrite the canonical entry for a URL. | |
| 93 | + // Background crawler: tops the cache up with pages no visitor has | |
| 94 | + // requested yet, a small batch at a time. | |
| 95 | + 'perf_page_cache_crawler' => false, | |
| 96 | + 'perf_page_cache_crawl_batch' => 20, | |
| 97 | + 'perf_page_cache_query_args' => [], | |
| 98 | + 'perf_page_cache_exclusions' => [], | |
| 99 | + // Performance Suite — move render-blocking inline CSS into cached | |
| 100 | + // files so the browser can reuse it across navigations. Off by | |
| 101 | + // default: it changes how every page's CSS is delivered. | |
| 102 | + 'perf_consolidate_css' => false, | |
| 103 | + // Runs smaller than this stay inline — below a couple of KB the | |
| 104 | + // extra request costs more than the bytes saved. | |
| 105 | + 'perf_consolidate_css_min' => 2048, | |
| 106 | + // Performance Suite — cache rendered FSE template parts (header, | |
| 107 | + // footer). Off by default: replaying a cached render's side effects | |
| 108 | + // is the delicate part, so it wants per-site verification. | |
| 109 | + 'perf_fragment_cache' => false, | |
| 110 | + 'perf_fragment_cache_ttl' => 43200, | |
| 111 | + // Performance Suite — memoise block template resolution. Measured at | |
| 112 | + // 11-14ms and 7-10 queries per request on a block theme. | |
| 113 | + 'perf_template_cache' => false, | |
| 114 | + 'perf_template_cache_ttl' => 43200, | |
| 115 | + // Image tools — recompress files on disk. Every part opt-in: unlike | |
| 116 | + // the delivery options above, these rewrite the user's media. | |
| 117 | + 'perf_image_optimize_on_upload' => false, | |
| 118 | + // '1x' gentle | '2x' balanced | '5x' aggressive | |
| 119 | + 'perf_image_level' => '2x', | |
| 120 | + 'perf_image_webp' => true, | |
| 121 | + 'perf_image_quarantine_autodelete' => false, | |
| 122 | + 'perf_image_quarantine_days' => 30, | |
| 123 | + // Upload standards. Filenames can be blocked outright; alt text cannot | |
| 124 | + // be required at upload time, so it gates use instead. See UploadGuard. | |
| 125 | + 'perf_image_require_filename' => false, | |
| 126 | + 'perf_image_require_alt' => false, | |
| 127 | + // Marketing — carry incoming affiliate/UTM query params onto tagged | |
| 128 | + // links so a visitor who lands on ?ref=xyz keeps that param as they | |
| 129 | + // click through. Opt-in; inert unless a tagged link is present AND a | |
| 130 | + // tracked param exists in the current URL. | |
| 131 | + 'param_passthrough_enabled' => false, | |
| 132 | + 'param_passthrough_keys' => 'ref,utm_source,utm_medium,utm_campaign,utm_term,utm_content', | |
| 133 | + // Which links receive the params: 'class' (only links tagged with the | |
| 134 | + // CSS class), 'all' (every same-site link), or 'keyword' (links whose | |
| 135 | + // URL contains one of the configured words). | |
| 136 | + 'param_passthrough_match' => 'class', | |
| 137 | + 'param_passthrough_class' => 'aff-link', | |
| 138 | + 'param_passthrough_keyword' => '', | |
| 139 | + // Remember the incoming params in a cookie so they keep being applied | |
| 140 | + // even after the visitor lands on a page whose URL no longer carries | |
| 141 | + // them (e.g. after clicking an untagged menu link). | |
| 142 | + 'param_passthrough_persist' => true, | |
| 143 | + 'param_passthrough_cookie_days' => 30, | |
| 144 | + 'enabled_coming_soon_page' => false, | |
| 145 | + 'coming_soon_page' => '', | |
| 146 | + 'enabled_maintenance_page' => false, | |
| 147 | + 'maintenance_page' => '', | |
| 148 | + 'frontend_dashboard_page' => '', | |
| 149 | + 'login_page' => '', | |
| 150 | + 'registration_page' => '', | |
| 151 | + 'forget_password_page' => '', | |
| 152 | + 'global_color' => [ | |
| 153 | + [ | |
| 154 | + 'id' => 'primary', | |
| 155 | + 'label' => 'Primary Color', | |
| 156 | + 'value' => '#6EC1E4', | |
| 157 | + 'is_system' => true, | |
| 158 | + ], | |
| 159 | + [ | |
| 160 | + 'id' => 'secondary', | |
| 161 | + 'label' => 'Secondary', | |
| 162 | + 'value' => '#54595F', | |
| 163 | + 'is_system' => true, | |
| 164 | + ], | |
| 165 | + [ | |
| 166 | + 'id' => 'text', | |
| 167 | + 'label' => 'Text', | |
| 168 | + 'value' => '#7A7A7A', | |
| 169 | + 'is_system' => true, | |
| 170 | + ], | |
| 171 | + [ | |
| 172 | + 'id' => 'accent', | |
| 173 | + 'label' => 'Accent', | |
| 174 | + 'value' => '#61CE70', | |
| 175 | + 'is_system' => true, | |
| 176 | + ], | |
| 177 | + ], | |
| 178 | + 'global_typography' => [ | |
| 179 | + [ | |
| 180 | + 'id' => 'primary', | |
| 181 | + 'label' => 'Primary', | |
| 182 | + 'value' => Typography::get_attribute_default_value( true, [] ), | |
| 183 | + 'is_system' => true, | |
| 184 | + ], | |
| 185 | + [ | |
| 186 | + 'id' => 'secondary', | |
| 187 | + 'label' => 'Secondary', | |
| 188 | + 'value' => Typography::get_attribute_default_value( true, [] ), | |
| 189 | + 'is_system' => true, | |
| 190 | + ], | |
| 191 | + [ | |
| 192 | + 'id' => 'text', | |
| 193 | + 'label' => 'Text', | |
| 194 | + 'value' => Typography::get_attribute_default_value( true, [] ), | |
| 195 | + 'is_system' => true, | |
| 196 | + ], | |
| 197 | + [ | |
| 198 | + 'id' => 'accent', | |
| 199 | + 'label' => 'Accent', | |
| 200 | + 'value' => Typography::get_attribute_default_value( true, [] ), | |
| 201 | + 'is_system' => true, | |
| 202 | + ], | |
| 203 | + ], | |
| 204 | + 'global_font_family_fallback' => 'Sans-serif', | |
| 205 | + // Global Typography and color | |
| 206 | + 'global_body_text_color' => '', | |
| 207 | + 'global_body_typography' => Typography::get_attribute_default_value( true, [] ), | |
| 208 | + 'global_body_paragraph_space' => Range::get_attribute_default_value( [ | |
| 209 | + 'isResponsive' => true, | |
| 210 | + 'defaultValue' => '', | |
| 211 | + 'defaultValueTablet' => '', | |
| 212 | + 'defaultValueMobile' => '', | |
| 213 | + 'hasUnit' => true, | |
| 214 | + 'unitDefaultValue' => 'px', | |
| 215 | + 'attributeObjectKey' => 'value', | |
| 216 | + ] ), | |
| 217 | + 'global_link_color' => '', | |
| 218 | + 'global_link_hover_color' => '', | |
| 219 | + 'global_link_typography' => Typography::get_attribute_default_value( true, [] ), | |
| 220 | + 'global_link_hover_typography' => Typography::get_attribute_default_value( true, [] ), | |
| 221 | + 'global_h1_color' => '', | |
| 222 | + 'global_h1_typography' => Typography::get_attribute_default_value( true, [] ), | |
| 223 | + 'global_h2_color' => '', | |
| 224 | + 'global_h2_typography' => Typography::get_attribute_default_value( true, [] ), | |
| 225 | + 'global_h3_color' => '', | |
| 226 | + 'global_h3_typography' => Typography::get_attribute_default_value( true, [] ), | |
| 227 | + 'global_h4_color' => '', | |
| 228 | + 'global_h4_typography' => Typography::get_attribute_default_value( true, [] ), | |
| 229 | + 'global_h5_color' => '', | |
| 230 | + 'global_h5_typography' => Typography::get_attribute_default_value( true, [] ), | |
| 231 | + 'global_h6_color' => '', | |
| 232 | + 'global_h6_typography' => Typography::get_attribute_default_value( true, [] ), | |
| 233 | + ]); | |
| 234 | + } | |
| 235 | + | |
| 236 | + public static function save_settings( $form_data = false ) { | |
| 237 | + $default_data = self::get_default_data(); | |
| 238 | + $saved_data = self::get_saved_data(); | |
| 239 | + $settings_data = wp_parse_args( $saved_data, $default_data ); | |
| 240 | + if ( $form_data ) { | |
| 241 | + $settings_data = wp_parse_args( $form_data, $settings_data ); | |
| 242 | + } | |
| 243 | + // if settings already saved, then update it | |
| 244 | + if ( count( $saved_data ) ) { | |
| 245 | + return update_option( ABLOCKS_SETTINGS_NAME, wp_json_encode( $settings_data ) ); | |
| 246 | + } | |
| 247 | + return add_option( ABLOCKS_SETTINGS_NAME, wp_json_encode( $settings_data ) ); | |
| 248 | + } | |
| 249 | +} | |