*/ public static function abilities(): array { return [ new Ability( 'sarcio/elementor-globals-get', __('Look at Elementor’s global colours and fonts', 'sarcio'), Ability::READ, 'Elementor’s global colours (system and custom, each with an id, a title and a hex value) and global fonts. Say when Elementor or its kit is missing.', ['properties' => [], 'required' => [], 'type' => 'object'], static fn (array $args): bool => current_user_can('edit_theme_options'), static fn (array $args): array => self::get(null), ), new Ability( 'sarcio/elementor-global-color-set', __('Change an Elementor global colour', 'sarcio'), Ability::WRITE, 'Set a global colour by its id from elementor-globals-get to a hex value (#RRGGBB). Every element using it changes. Previewed first; undo puts the old colour back.', ['properties' => ['color' => ['pattern' => '^#[0-9a-fA-F]{6}$', 'type' => 'string'], 'id' => ['maxLength' => 40, 'minLength' => 1, 'type' => 'string']], 'required' => ['color', 'id'], 'type' => 'object'], static fn (array $args): bool => current_user_can('edit_theme_options'), static fn (array $args): array => self::setColor($args), null, static fn (array $before, array $after): array => self::writeColor((string) $before['id'], (string) $before['color']) + ['restored' => true], false, static fn (array $args, Overlay $overlay): array => self::stageColor($args, $overlay), ), ]; } public static function kitId(): int { return defined('ELEMENTOR_VERSION') ? (int) get_option('elementor_active_kit', 0) : 0; } /** @return array|null */ private static function settings(?Overlay $overlay): ?array { $kit = self::kitId(); if ($kit <= 0) { return null; } $staged = $overlay?->meta[$kit][self::SETTINGS] ?? null; $settings = $staged ?? get_post_meta($kit, self::SETTINGS, true); return is_array($settings) ? $settings : []; } private static function get(?Overlay $overlay): array { $settings = self::settings($overlay); if ($settings === null) { return ['error' => __('Elementor is not on this site, or has no active kit yet.', 'sarcio')]; } $colors = []; foreach (['system_colors', 'custom_colors'] as $group) { foreach ((array) ($settings[$group] ?? []) as $color) { if (is_array($color) && isset($color['_id'])) { $colors[] = ['color' => (string) ($color['color'] ?? ''), 'group' => $group === 'system_colors' ? 'system' : 'custom', 'id' => (string) $color['_id'], 'title' => (string) ($color['title'] ?? '')]; } } } $fonts = []; foreach (['system_typography', 'custom_typography'] as $group) { foreach ((array) ($settings[$group] ?? []) as $font) { if (is_array($font) && isset($font['_id'])) { $fonts[] = ['family' => (string) ($font['typography_font_family'] ?? ''), 'id' => (string) $font['_id'], 'title' => (string) ($font['title'] ?? ''), 'weight' => (string) ($font['typography_font_weight'] ?? '')]; } } } return ['colors' => $colors, 'fonts' => $fonts, 'kit' => self::kitId()]; } /** @return array{0:array,1:string,2:string}|array{error:string} settings with the colour set, the group, the old value */ private static function withColor(?Overlay $overlay, string $id, string $color): array { $settings = self::settings($overlay); if ($settings === null) { return ['error' => __('Elementor is not on this site, or has no active kit yet.', 'sarcio')]; } foreach (['system_colors', 'custom_colors'] as $group) { foreach ((array) ($settings[$group] ?? []) as $i => $entry) { if (is_array($entry) && (string) ($entry['_id'] ?? '') === $id) { $before = (string) ($entry['color'] ?? ''); if (strcasecmp($before, $color) === 0) { return ['error' => __('Nothing would change.', 'sarcio')]; } $settings[$group][$i]['color'] = $color; return [$settings, $group, $before]; } } } return ['error' => __('There is no global colour with that id.', 'sarcio')]; } /** @param array $args */ private static function stageColor(array $args, Overlay $overlay): array { $color = strtoupper((string) $args['color']); $result = self::withColor($overlay, (string) $args['id'], $color); if (isset($result['error'])) { return $result; } $overlay->setMeta(self::kitId(), self::SETTINGS, $result[0]); $overlay->setMeta(self::kitId(), '_elementor_css', ''); return [ 'after' => $color, 'before' => $result[2], 'summary' => sprintf( /* translators: 1: the colour id, 2: the new value. */ __('Set the Elementor global colour %1$s to %2$s', 'sarcio'), (string) $args['id'], $color, ), ]; } /** @param array $args */ private static function setColor(array $args): array { $color = strtoupper((string) $args['color']); $result = self::withColor(null, (string) $args['id'], $color); if (isset($result['error'])) { return $result; } self::store($result[0]); return [ 'color' => $color, 'journal' => [ 'after' => ['color' => $color, 'id' => (string) $args['id']], 'before' => ['color' => $result[2], 'id' => (string) $args['id']], 'summary' => sprintf( /* translators: 1: the colour id, 2: the new value. */ __('Set the Elementor global colour %1$s to %2$s', 'sarcio'), (string) $args['id'], $color, ), 'target' => 'elementor-kit:' . self::kitId(), ], ]; } private static function writeColor(string $id, string $color): array { $result = self::withColor(null, $id, $color); if (isset($result['error'])) { return $result; } self::store($result[0]); return ['color' => $color]; } /** @param array $settings */ private static function store(array $settings): void { $kit = self::kitId(); update_post_meta($kit, self::SETTINGS, $settings); delete_post_meta($kit, '_elementor_css'); if (class_exists('\Elementor\Plugin') && isset(\Elementor\Plugin::$instance->files_manager)) { \Elementor\Plugin::$instance->files_manager->clear_cache(); } } }