PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.9.7
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.9.7
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.7, at includes/registries/wallpapers.php

283 lines 9.9 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.8.1
58 * @since 0.8.1 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 $description Plain-text description shown in OS
83 * Settings when the wallpaper is the
84 * active selection — what it is, where
85 * its data comes from, the story behind
86 * it. Optional. Since 0.9.4.
87 * @type string[] $capabilities Gate: ALL caps must match. Any
88 * missed cap returns
89 * `WP_Error desktop_mode_capability_denied`.
90 * }
91 * @return true|WP_Error `true` on success; `WP_Error` otherwise.
92 */
93 function desktop_mode_register_wallpaper( $id, $args = array() ) {
94 $id = (string) $id;
95 if ( '' === $id ) {
96 return desktop_mode_registration_error(
97 'desktop_mode_missing_id',
98 __( 'Wallpaper id is required.', 'desktop-mode' )
99 );
100 }
101
102 $defaults = array(
103 'label' => '',
104 'preview' => '',
105 'type' => 'canvas',
106 'value' => '',
107 'script' => '',
108 'description' => '',
109 'capabilities' => array(),
110 );
111 $args = wp_parse_args( $args, $defaults );
112
113 foreach ( (array) $args['capabilities'] as $cap ) {
114 if ( ! current_user_can( (string) $cap ) ) {
115 return desktop_mode_registration_error(
116 'desktop_mode_capability_denied',
117 sprintf(
118 /* translators: %s: capability slug. */
119 __( 'Current user lacks the %s capability required to register this wallpaper.', 'desktop-mode' ),
120 (string) $cap
121 ),
122 array( 'capability' => (string) $cap, 'id' => $id )
123 );
124 }
125 }
126 if ( '' === (string) $args['label'] ) {
127 return desktop_mode_registration_error(
128 'desktop_mode_missing_label',
129 __( 'Wallpaper registration requires a non-empty `label`.', 'desktop-mode' ),
130 array( 'id' => $id )
131 );
132 }
133 $type = in_array( $args['type'], array( 'css', 'canvas' ), true )
134 ? $args['type']
135 : 'canvas';
136 // Canvas wallpapers always need a script (the def with its
137 // `mount` callback is published on the JS global by that
138 // script). CSS wallpapers can skip the script — the shell can
139 // render from the `value` / `preview` string alone.
140 if ( 'canvas' === $type && '' === (string) $args['script'] ) {
141 return desktop_mode_registration_error(
142 'desktop_mode_missing_script',
143 __( 'Canvas wallpaper registration requires a `script` handle that publishes the def.', 'desktop-mode' ),
144 array( 'id' => $id )
145 );
146 }
147
148 // `value` defaults to `preview` when omitted — the common case
149 // for a plain gradient/solid where the swatch and the surface
150 // render the same CSS. Authors can split them (e.g. static
151 // swatch preview + animated value) by passing both.
152 $value = (string) $args['value'];
153 if ( '' === $value ) {
154 $value = (string) $args['preview'];
155 }
156
157 $entry = array(
158 'id' => $id,
159 'label' => (string) $args['label'],
160 'preview' => (string) $args['preview'],
161 'type' => $type,
162 'value' => $value,
163 'script' => (string) $args['script'],
164 // Plain text by contract — the shell renders it as text, never
165 // as HTML, so strip tags here rather than trusting every caller.
166 'description' => sanitize_textarea_field( (string) $args['description'] ),
167 );
168 desktop_mode_desktop_wallpaper_registry( $id, $entry );
169
170 /**
171 * Fires after a desktop wallpaper is successfully registered.
172 *
173 * Does NOT fire when `desktop_mode_register_wallpaper()` returns a
174 * `WP_Error`.
175 *
176 * @since 0.8.1
177 *
178 * @param string $id The wallpaper id.
179 * @param array $entry The stored registry entry.
180 */
181 do_action( 'desktop_mode_wallpaper_registered', $id, $entry );
182
183 return true;
184 }
185
186 /**
187 * Internal module-level registry for wallpapers registered via
188 * {@see desktop_mode_register_wallpaper()}. Same static-store
189 * pattern as the widget + native-window registries.
190 *
191 * @since 0.8.1
192 * @internal
193 */
194 function desktop_mode_desktop_wallpaper_registry( $id = '', $entry = null ) {
195 static $store = array();
196
197 if ( '' === (string) $id ) {
198 return $store;
199 }
200 if ( null !== $entry ) {
201 $store[ $id ] = $entry;
202 }
203 return isset( $store[ $id ] ) ? $store[ $id ] : null;
204 }
205
206 /**
207 * Build the wallpaper list for the shell payload. Only metadata +
208 * the resolved script URL cross the wire; the plugin's mount
209 * callback is announced via the JS global the script sets up.
210 *
211 * @since 0.8.1
212 *
213 * @return array[]
214 */
215 function desktop_mode_build_desktop_wallpapers_payload() {
216 $registry = desktop_mode_desktop_wallpaper_registry();
217 if ( ! is_array( $registry ) || empty( $registry ) ) {
218 return array();
219 }
220 /**
221 * Filters the server-declared wallpaper list before it ships to
222 * the shell. Mirrors the JS-side `desktop-mode.wallpapers` filter
223 * so plugins can rearrange, hide, or override entries at boot
224 * without round-tripping through the JS registry.
225 *
226 * @since 0.8.1
227 *
228 * @param array[] $registry The registered wallpaper entries.
229 */
230 $registry = apply_filters( 'desktop_mode_wallpapers', $registry );
231 if ( ! is_array( $registry ) ) {
232 return array();
233 }
234 $out = array();
235 foreach ( $registry as $entry ) {
236 if ( ! is_array( $entry ) || empty( $entry['id'] ) ) {
237 continue;
238 }
239 $handle = isset( $entry['script'] ) ? (string) $entry['script'] : '';
240 $payload = desktop_mode_resolve_script_payload( $handle );
241 $out[] = array(
242 'id' => (string) $entry['id'],
243 'label' => isset( $entry['label'] ) ? (string) $entry['label'] : '',
244 'preview' => isset( $entry['preview'] ) ? (string) $entry['preview'] : '',
245 'type' => isset( $entry['type'] ) ? (string) $entry['type'] : 'canvas',
246 'value' => isset( $entry['value'] ) ? (string) $entry['value'] : '',
247 'description' => isset( $entry['description'] ) ? (string) $entry['description'] : '',
248 'scriptUrl' => $payload['url'],
249 'scriptHandle' => $handle,
250 'scriptBefore' => $payload['before'],
251 'scriptAfter' => $payload['after'],
252 'scriptL10n' => $payload['l10n'],
253 'scriptTranslations' => $payload['translations'],
254 );
255 }
256 return $out;
257 }
258
259
260 /**
261 * Enqueue plugin-registered wallpaper scripts on the shell page
262 * so wallpapers active at boot time have their defs available
263 * without any dynamic-load roundtrip.
264 *
265 * @since 0.8.1
266 */
267 function desktop_mode_enqueue_desktop_wallpaper_scripts() {
268 if ( ! desktop_mode_is_enabled() || desktop_mode_is_chromeless_request() || desktop_mode_is_classic_request() ) {
269 return;
270 }
271 $registry = desktop_mode_desktop_wallpaper_registry();
272 if ( ! is_array( $registry ) ) {
273 return;
274 }
275 foreach ( $registry as $entry ) {
276 if ( ! empty( $entry['script'] ) ) {
277 wp_enqueue_script( $entry['script'] );
278 }
279 }
280 }
281 add_action( 'admin_enqueue_scripts', 'desktop_mode_enqueue_desktop_wallpaper_scripts', 20 );
282
283