PluginProbe
Extendify / 3.1.6
Extendify v3.1.6
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / app / Shared / Services / BlockStyleVariations.php

BlockStyleVariations.php in Extendify 3.1.6, at app/Shared/Services/BlockStyleVariations.php

123 lines 3.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Extendify\Shared\Services;
4
5 defined('ABSPATH') || die('No direct access.');
6
7 /**
8 * WordPress sanitizes user global styles against the block style registry, so an
9 * unregistered variation name is dropped from every read of the stored styles
10 * and its CSS never compiles.
11 */
12 class BlockStyleVariations
13 {
14 /**
15 * Variation names per block type, as last written to global styles.
16 *
17 * @var string
18 */
19 // phpcs:ignore PSR12.Properties.ConstantVisibility.NotFound
20 const OPTION = 'extendify_block_style_variations';
21
22 /**
23 * @return void
24 */
25 public static function register()
26 {
27 // Late, so a theme registering the same name keeps its own label.
28 add_action('init', [self::class, 'registerStored'], 99);
29 add_filter('rest_request_before_callbacks', [self::class, 'registerIncoming'], 10, 3);
30 }
31
32 /**
33 * @return void
34 */
35 public static function registerStored()
36 {
37 self::registerNames(get_option(self::OPTION, []));
38 }
39
40 /**
41 * A design flow's write carries the names it needs, so nothing is fetched or
42 * guessed. Runs before the controller sanitizes the incoming JSON.
43 *
44 * @param mixed $response - The REST response, passed through untouched.
45 * @param array $handler - The matched route handler.
46 * @param \WP_REST_Request $request - The incoming request.
47 * @return mixed
48 */
49 public static function registerIncoming($response, $handler, $request)
50 {
51 $isWrite = in_array($request->get_method(), ['POST', 'PUT', 'PATCH'], true);
52 if (!$isWrite || strpos($request->get_route(), '/wp/v2/global-styles') !== 0) {
53 return $response;
54 }
55
56 $names = self::namesInWrite($request->get_param('styles'));
57 if (!$names) {
58 return $response;
59 }
60
61 self::registerNames($names);
62 update_option(self::OPTION, self::mergeNames(get_option(self::OPTION, []), $names));
63
64 return $response;
65 }
66
67 /**
68 * @param mixed $styles - The styles node of a global styles write.
69 * @return array<string, array<string>>
70 */
71 private static function namesInWrite($styles)
72 {
73 $blocks = is_array($styles) ? ($styles['blocks'] ?? []) : [];
74 $names = [];
75 foreach ((array) $blocks as $blockType => $block) {
76 $variations = is_array($block) ? ($block['variations'] ?? []) : [];
77 $ours = array_filter(array_keys((array) $variations), function ($name) {
78 return is_string($name) && strpos($name, 'ext-') === 0;
79 });
80
81 if ($ours) {
82 $names[$blockType] = array_values($ours);
83 }
84 }
85
86 return $names;
87 }
88
89 /**
90 * @param mixed $stored - The names already persisted.
91 * @param array<string, array<string>> $names - The names to add.
92 * @return array<string, array<string>>
93 */
94 private static function mergeNames($stored, $names)
95 {
96 $merged = is_array($stored) ? $stored : [];
97 foreach ($names as $blockType => $blockNames) {
98 $existing = (array) ($merged[$blockType] ?? []);
99 $merged[$blockType] = array_values(array_unique(array_merge($existing, $blockNames)));
100 }
101
102 return $merged;
103 }
104
105 /**
106 * @param mixed $names - Variation names per block type.
107 * @return void
108 */
109 private static function registerNames($names)
110 {
111 $registry = \WP_Block_Styles_Registry::get_instance();
112 foreach ((array) $names as $blockType => $blockNames) {
113 foreach ((array) $blockNames as $name) {
114 if (!is_string($blockType) || !is_string($name) || $registry->is_registered($blockType, $name)) {
115 continue;
116 }
117
118 \register_block_style($blockType, ['name' => $name, 'label' => $name]);
119 }
120 }
121 }
122 }
123