| @@ -1,0 +1,111 @@ | ||
| 1 | +<?php | |
| 2 | +namespace ABlocks\Classes; | |
| 3 | + | |
| 4 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 5 | + exit; | |
| 6 | +} | |
| 7 | + | |
| 8 | +use ABlocks\Helper; | |
| 9 | + | |
| 10 | +abstract class ControlBaseAbstract { | |
| 11 | + abstract public static function get_attribute_default_value( $is_responsive = false); | |
| 12 | + abstract public static function get_attribute( $attributeName, $is_responsive = false); | |
| 13 | + abstract public static function get_css( $attribute_value, $property = '', $device = ''); | |
| 14 | + public static function has_value( $value ) { | |
| 15 | + return isset( $value ) && ! empty( $value ); | |
| 16 | + } | |
| 17 | + | |
| 18 | + /** | |
| 19 | + * Read one device-suffixed member of a control's value. | |
| 20 | + * | |
| 21 | + * A control's defaults only declare the built-in suffixes ('', 'Tablet', | |
| 22 | + * 'Mobile'), so any other device — a user-registered custom breakpoint, or | |
| 23 | + * the value-less probe suffix CssGenerator uses to subtract a baseline — | |
| 24 | + * has no key at all. Reading it directly emits "Undefined array key" under | |
| 25 | + * WP_DEBUG on every page. Missing reads as unset, which is what the callers | |
| 26 | + * already treated the resulting null as. | |
| 27 | + * | |
| 28 | + * @param array $value The control's parsed value. | |
| 29 | + * @param string $base Member name without the device suffix. | |
| 30 | + * @param string $device Device suffix ('' | 'Tablet' | 'Mobile' | 'Bp…'). | |
| 31 | + * @param mixed $default Returned when the key is absent. | |
| 32 | + * @return mixed | |
| 33 | + */ | |
| 34 | + public static function device_member( $value, $base, $device = '', $default = '' ) { | |
| 35 | + $key = $base . $device; | |
| 36 | + return array_key_exists( $key, (array) $value ) ? $value[ $key ] : $default; | |
| 37 | + } | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * Cached responsive_defaults() results, keyed by control class. | |
| 41 | + * | |
| 42 | + * @var array | |
| 43 | + */ | |
| 44 | + private static $responsive_defaults_cache = []; | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * The control's responsive defaults, extended to cover every device suffix a | |
| 48 | + * compiler can ask for. | |
| 49 | + * | |
| 50 | + * Controls declare defaults for the built-in suffixes only ('', 'Tablet', | |
| 51 | + * 'Mobile'), but CssGenerator also calls get_css() with each user-registered | |
| 52 | + * custom-breakpoint suffix and with a value-less probe suffix. Those keys | |
| 53 | + * exist nowhere, so every `$value[ 'top' . $device ]` in a control emitted an | |
| 54 | + * "Undefined array key" notice. Mirroring each responsive member onto the | |
| 55 | + * extra suffixes — defaulted to the desktop value, i.e. "nothing overridden | |
| 56 | + * here" — makes those reads defined without changing a single output: a | |
| 57 | + * device with no stored value already compiled as unset. | |
| 58 | + * | |
| 59 | + * Use in place of `get_attribute_default_value( true )` when parsing a value | |
| 60 | + * for get_css(). | |
| 61 | + * | |
| 62 | + * @return array Defaults covering '', 'Tablet', 'Mobile' and every extra suffix. | |
| 63 | + */ | |
| 64 | + public static function responsive_defaults() { | |
| 65 | + $cache_key = static::class; | |
| 66 | + if ( isset( self::$responsive_defaults_cache[ $cache_key ] ) ) { | |
| 67 | + return self::$responsive_defaults_cache[ $cache_key ]; | |
| 68 | + } | |
| 69 | + | |
| 70 | + $defaults = (array) static::get_attribute_default_value( true ); | |
| 71 | + | |
| 72 | + $suffixes = [ '__ablocksphantom__' ]; | |
| 73 | + foreach ( Helper::get_responsive_devices() as $device ) { | |
| 74 | + $suffix = isset( $device['suffix'] ) ? $device['suffix'] : ''; | |
| 75 | + if ( '' === $suffix || 'Tablet' === $suffix || 'Mobile' === $suffix ) { | |
| 76 | + continue; | |
| 77 | + } | |
| 78 | + $suffixes[] = $suffix; | |
| 79 | + } | |
| 80 | + | |
| 81 | + foreach ( array_keys( $defaults ) as $key ) { | |
| 82 | + if ( 'Tablet' !== substr( $key, -6 ) ) { | |
| 83 | + continue; | |
| 84 | + } | |
| 85 | + $base = substr( $key, 0, -6 ); | |
| 86 | + foreach ( $suffixes as $suffix ) { | |
| 87 | + if ( array_key_exists( $base . $suffix, $defaults ) ) { | |
| 88 | + continue; | |
| 89 | + } | |
| 90 | + // Copy the TABLET default, not the desktop one. A responsive | |
| 91 | + // suffix's default means "nothing overridden at this device", | |
| 92 | + // which is what Tablet/Mobile already encode; the desktop entry | |
| 93 | + // is the base value and can be a real setting (Alignment's is | |
| 94 | + // the literal 'default'), which would then be emitted as a CSS | |
| 95 | + // declaration for every custom breakpoint. | |
| 96 | + $defaults[ $base . $suffix ] = $defaults[ $key ]; | |
| 97 | + } | |
| 98 | + } | |
| 99 | + | |
| 100 | + self::$responsive_defaults_cache[ $cache_key ] = $defaults; | |
| 101 | + return $defaults; | |
| 102 | + } | |
| 103 | + public static function get_unit( $attribute_value, $device = '' ) { | |
| 104 | + return Helper::get_responsive_value( | |
| 105 | + $attribute_value, | |
| 106 | + 'unit', | |
| 107 | + $device, | |
| 108 | + [] | |
| 109 | + ); | |
| 110 | + } | |
| 111 | +} | |