settings->breakpoints(); } catch (\Throwable $e) { $all = null; } } if (!is_array($all)) { $all = \Zadex\Settings::default_breakpoints(); } $out = []; foreach ($all as $key => $bp) { if ($key === 'desktop' || !is_array($bp) || empty($bp['enabled']) || ($bp['direction'] ?? 'max') !== 'max') { continue; } $out[$key] = (int) ($bp['value'] ?? 0); } return $out; } /** * Slides per view per breakpoint, `{desktop: n, tablet?: n, mobile?: n}`. * * @param array $settings * @param array $breakpoints */ public static function slides(array $settings, array $breakpoints, int $fallback = 3): array { $out = ['desktop' => max(1, (int) ($settings['slides_to_show'] ?? $fallback) ?: $fallback)]; foreach (array_keys($breakpoints) as $key) { $v = $settings['slides_to_show@' . $key] ?? null; if (is_numeric($v) && (int) $v > 0) { $out[$key] = (int) $v; } } return $out; } /** * Adds the slider class, options and layout variables to a widget's root attribute string. * * @param array $settings * @param array{classes?: string[], slides?: array, loop?: bool, extra?: array, style?: string} $opts */ public static function attrs(string $attrs, array $settings, array $opts = []): string { $breakpoints = self::breakpoints(); $slides = $opts['slides'] ?? self::slides($settings, $breakpoints); $gap_value = $settings['gap'] ?? ['size' => 20, 'unit' => 'px']; $gap = max(0, is_array($gap_value) ? (int) ($gap_value['size'] ?? 0) : (int) $gap_value); $autoplay = !empty($settings['autoplay']) ? max(500, (int) ($settings['autoplay_speed'] ?? 4000)) : 0; $loop = array_key_exists('loop', $opts) ? (bool) $opts['loop'] : !empty($settings['loop']); $classes = trim('zx-slider ' . implode(' ', array_map('sanitize_html_class', $opts['classes'] ?? []))); $attrs = (string) preg_replace('/class="/', 'class="' . $classes . ' ', $attrs, 1); $attrs .= ' data-zx-slides="' . esc_attr((string) wp_json_encode($slides)) . '"'; $attrs .= ' data-zx-breakpoints="' . esc_attr((string) wp_json_encode((object) $breakpoints)) . '"'; $attrs .= ' data-zx-scroll="' . max(1, (int) ($settings['slides_to_scroll'] ?? 1)) . '" data-zx-gap="' . $gap . '" data-zx-speed="' . max(0, (int) ($settings['speed'] ?? 400)) . '"'; $attrs .= ' data-zx-loop="' . ($loop ? 'true' : 'false') . '" data-zx-autoplay="' . ($autoplay ?: 'false') . '" data-zx-pause="' . (($settings['pause_on_hover'] ?? true) ? 'true' : 'false') . '"'; $attrs .= ' data-zx-arrows="' . (!empty($settings['arrows']) ? 'true' : 'false') . '" data-zx-dots="' . (!empty($settings['dots']) ? 'true' : 'false') . '"'; foreach ($opts['extra'] ?? [] as $name => $value) { $attrs .= ' ' . preg_replace('/[^a-z0-9\-]/', '', strtolower((string) $name)) . '="' . esc_attr((string) $value) . '"'; } $attrs .= ' style="--zx-spv:' . (int) $slides['desktop'] . ';--zx-gap:' . $gap . 'px' . (isset($opts['style']) ? ';' . esc_attr($opts['style']) : '') . '"'; return $attrs; } /** Previous / next buttons (`__arrow`), theme-shielded (has-text-color has-background). */ public static function arrows(string $prefix): string { $p = sanitize_html_class($prefix); $svg = static fn(string $d): string => ''; return '' . ''; } public static function dots(string $prefix): string { return '
'; } }