PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.9.2
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.9.2
1.1.10 1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 All 34 releases
desktop-mode / includes / registries / wallpapers.php

wallpapers.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 0.9.2, at includes/registries/wallpapers.php

273 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Desktop Mode — Wallpapers registry.
4 *
5 * Server-side registration API + payload builder + asset enqueue
6 * for the desktop wallpaper picker. Wallpaper definitions live
7 * on `window.desktopModeWallpapers[ id ]` (set by the plugin's
8 * own JS); this module is the PHP side that announces them to
9 * the shell and ships their script handles into the boot
10 * payload.
11 *
12 * Extracted from `components.php` during the architecture-0.8.1
13 * PHP slicing (phase 6). Behaviour, function names, filter
14 * contracts, and error codes all unchanged.
15 *
16 * @package Desktop_Mode
17 * @since 0.8.1
18 */
19
20 defined( 'ABSPATH' ) || exit;
21
22 /**
23 * Register a server-side desktop wallpaper. Symmetrical to
24 * {@see desktop_mode_register_widget()}. The plugin's JS side
25 * publishes the full `WallpaperDef` (with mount / resolveValue /
26 * renderEditor callbacks as appropriate) on
27 * `window.desktopModeWallpapers[ <id> ]`; the shell loads the
28 * declared script, reads that global, and registers the def via
29 * the normal wallpaper registry. Deactivation unregisters the
30 * def and re-applies the current selection (which falls back to
31 * a built-in if the user's active wallpaper was the one leaving).
32 *
33 * Example:
34 *
35 * ```php
36 * desktop_mode_register_wallpaper( 'myplugin/snow', array(
37 * 'label' => __( 'Snow', 'my-plugin' ),
38 * 'preview' => 'linear-gradient(#fff, #ddd)',
39 * 'type' => 'canvas',
40 * 'script' => 'my-plugin-snow-wallpaper',
41 * ) );
42 * ```
43 *
44 * ```js
45 * // Inside my-plugin-snow-wallpaper.js
46 * window.desktopModeWallpapers = window.desktopModeWallpapers || {};
47 * window.desktopModeWallpapers[ 'myplugin/snow' ] = {
48 * id: 'myplugin/snow',
49 * label: 'Snow',
50 * type: 'canvas',
51 * preview: 'linear-gradient(#fff, #ddd)',
52 * needs: [ 'pixijs' ],
53 * mount: function ( container, ctx ) { return function () {}; },
54 * };
55 * ```
56 *
57 * @since 0.10.0
58 * @since 0.11.0 Returns `WP_Error` on validation failure instead of
59 * silent `false`. Legacy `if ( $result )` callers remain
60 * correct because `WP_Error` is truthy.
61 *
62 * @param string $id Wallpaper id. For canvas wallpapers this must
63 * match the `window.desktopModeWallpapers[<id>]`
64 * key the plugin's JS publishes.
65 * @param array $args {
66 * @type string $label Picker label. Required.
67 * @type string $preview CSS value rendered in the picker
68 * swatch (gradient, color,
69 * `url(...)`, etc.). Required.
70 * @type string $type 'css' | 'canvas'. Default 'canvas'.
71 * @type string $value CSS value applied to the wallpaper
72 * surface (only relevant for `css`
73 * type — canvas wallpapers paint in
74 * JS). Defaults to `preview` so a
75 * single string covers the common
76 * case where swatch and surface are
77 * identical.
78 * @type string $script Enqueued script handle that
79 * publishes the def on the global.
80 * Required for `canvas` type;
81 * optional for `css`.
82 * @type string[] $capabilities Gate: ALL caps must match. Any
83 * missed cap returns
84 * `WP_Error desktop_mode_capability_denied`.
85 * }
86 * @return true|WP_Error `true` on success; `WP_Error` otherwise.
87 */
88 function desktop_mode_register_wallpaper( $id, $args = array() ) {
89 $id = (string) $id;
90 if ( '' === $id ) {
91 return desktop_mode_registration_error(
92 'desktop_mode_missing_id',
93 __( 'Wallpaper id is required.', 'desktop-mode' )
94 );
95 }
96
97 $defaults = array(
98 'label' => '',
99 'preview' => '',
100 'type' => 'canvas',
101 'value' => '',
102 'script' => '',
103 'capabilities' => array(),
104 );
105 $args = wp_parse_args( $args, $defaults );
106
107 foreach ( (array) $args['capabilities'] as $cap ) {
108 if ( ! current_user_can( (string) $cap ) ) {
109 return desktop_mode_registration_error(
110 'desktop_mode_capability_denied',
111 sprintf(
112 /* translators: %s: capability slug. */
113 __( 'Current user lacks the %s capability required to register this wallpaper.', 'desktop-mode' ),
114 (string) $cap
115 ),
116 array( 'capability' => (string) $cap, 'id' => $id )
117 );
118 }
119 }
120 if ( '' === (string) $args['label'] ) {
121 return desktop_mode_registration_error(
122 'desktop_mode_missing_label',
123 __( 'Wallpaper registration requires a non-empty `label`.', 'desktop-mode' ),
124 array( 'id' => $id )
125 );
126 }
127 $type = in_array( $args['type'], array( 'css', 'canvas' ), true )
128 ? $args['type']
129 : 'canvas';
130 // Canvas wallpapers always need a script (the def with its
131 // `mount` callback is published on the JS global by that
132 // script). CSS wallpapers can skip the script — the shell can
133 // render from the `value` / `preview` string alone.
134 if ( 'canvas' === $type && '' === (string) $args['script'] ) {
135 return desktop_mode_registration_error(
136 'desktop_mode_missing_script',
137 __( 'Canvas wallpaper registration requires a `script` handle that publishes the def.', 'desktop-mode' ),
138 array( 'id' => $id )
139 );
140 }
141
142 // `value` defaults to `preview` when omitted — the common case
143 // for a plain gradient/solid where the swatch and the surface
144 // render the same CSS. Authors can split them (e.g. static
145 // swatch preview + animated value) by passing both.
146 $value = (string) $args['value'];
147 if ( '' === $value ) {
148 $value = (string) $args['preview'];
149 }
150
151 $entry = array(
152 'id' => $id,
153 'label' => (string) $args['label'],
154 'preview' => (string) $args['preview'],
155 'type' => $type,
156 'value' => $value,
157 'script' => (string) $args['script'],
158 );
159 desktop_mode_desktop_wallpaper_registry( $id, $entry );
160
161 /**
162 * Fires after a desktop wallpaper is successfully registered.
163 *
164 * Does NOT fire when `desktop_mode_register_wallpaper()` returns a
165 * `WP_Error`.
166 *
167 * @since 0.11.0
168 *
169 * @param string $id The wallpaper id.
170 * @param array $entry The stored registry entry.
171 */
172 do_action( 'desktop_mode_wallpaper_registered', $id, $entry );
173
174 return true;
175 }
176
177 /**
178 * Internal module-level registry for wallpapers registered via
179 * {@see desktop_mode_register_wallpaper()}. Same static-store
180 * pattern as the widget + native-window registries.
181 *
182 * @since 0.10.0
183 * @internal
184 */
185 function desktop_mode_desktop_wallpaper_registry( $id = '', $entry = null ) {
186 static $store = array();
187
188 if ( '' === (string) $id ) {
189 return $store;
190 }
191 if ( null !== $entry ) {
192 $store[ $id ] = $entry;
193 }
194 return isset( $store[ $id ] ) ? $store[ $id ] : null;
195 }
196
197 /**
198 * Build the wallpaper list for the shell payload. Only metadata +
199 * the resolved script URL cross the wire; the plugin's mount
200 * callback is announced via the JS global the script sets up.
201 *
202 * @since 0.10.0
203 *
204 * @return array[]
205 */
206 function desktop_mode_build_desktop_wallpapers_payload() {
207 $registry = desktop_mode_desktop_wallpaper_registry();
208 if ( ! is_array( $registry ) || empty( $registry ) ) {
209 return array();
210 }
211 /**
212 * Filters the server-declared wallpaper list before it ships to
213 * the shell. Mirrors the JS-side `desktop-mode.wallpapers` filter
214 * so plugins can rearrange, hide, or override entries at boot
215 * without round-tripping through the JS registry.
216 *
217 * @since 0.11.0
218 *
219 * @param array[] $registry The registered wallpaper entries.
220 */
221 $registry = apply_filters( 'desktop_mode_wallpapers', $registry );
222 if ( ! is_array( $registry ) ) {
223 return array();
224 }
225 $out = array();
226 foreach ( $registry as $entry ) {
227 if ( ! is_array( $entry ) || empty( $entry['id'] ) ) {
228 continue;
229 }
230 $handle = isset( $entry['script'] ) ? (string) $entry['script'] : '';
231 $payload = desktop_mode_resolve_script_payload( $handle );
232 $out[] = array(
233 'id' => (string) $entry['id'],
234 'label' => isset( $entry['label'] ) ? (string) $entry['label'] : '',
235 'preview' => isset( $entry['preview'] ) ? (string) $entry['preview'] : '',
236 'type' => isset( $entry['type'] ) ? (string) $entry['type'] : 'canvas',
237 'value' => isset( $entry['value'] ) ? (string) $entry['value'] : '',
238 'scriptUrl' => $payload['url'],
239 'scriptHandle' => $handle,
240 'scriptBefore' => $payload['before'],
241 'scriptAfter' => $payload['after'],
242 'scriptL10n' => $payload['l10n'],
243 'scriptTranslations' => $payload['translations'],
244 );
245 }
246 return $out;
247 }
248
249
250 /**
251 * Enqueue plugin-registered wallpaper scripts on the shell page
252 * so wallpapers active at boot time have their defs available
253 * without any dynamic-load roundtrip.
254 *
255 * @since 0.10.0
256 */
257 function desktop_mode_enqueue_desktop_wallpaper_scripts() {
258 if ( ! desktop_mode_is_enabled() || desktop_mode_is_chromeless_request() || desktop_mode_is_classic_request() ) {
259 return;
260 }
261 $registry = desktop_mode_desktop_wallpaper_registry();
262 if ( ! is_array( $registry ) ) {
263 return;
264 }
265 foreach ( $registry as $entry ) {
266 if ( ! empty( $entry['script'] ) ) {
267 wp_enqueue_script( $entry['script'] );
268 }
269 }
270 }
271 add_action( 'admin_enqueue_scripts', 'desktop_mode_enqueue_desktop_wallpaper_scripts', 20 );
272
273