PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.12
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.12
1.1.12 1.1.11 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 All 36 releases
← All changes | includes/workspaces.php +52 -1 1.1.6 → 1.1.12 View file →
@@ -95,10 +95,16 @@
95 95 * for — the JS token lists name WooCommerce and Sensei directly — so
96 96 * on a site that has them, Commerce is a WooCommerce desk in
97 97 * everything but its label.
98 98 *
99 + * And on a site that does not have them, the template is left out:
100 + * `requires` names the plugin, and this is the side of the wire that
101 + * knows whether it is active. The client's switcher shows what this
102 + * list names — see `installWorkspacePresetSync()` — so dropping an
103 + * entry here is what hides the card.
104 + *
99 105 * Filterable so a site can add a template, or drop one it has no use
100 - * for. A blog with no store has no reason to be offered a Woo desk.
106 + * for.
101 107 *
102 108 * @return array[] List of `array{ id, label, description, icon, color, layout }`.
103 109 */
104 110 function openstation_workspace_presets() {
@@ -110,8 +116,9 @@
110 116 'icon' => 'dashicons-cart',
111 117 'color' => '#7f54b3',
112 118 'layout' => 'columns',
113 119 'order' => 10,
120 + 'requires' => array( 'woocommerce/woocommerce.php' ),
114 121 ),
115 122 array(
116 123 'id' => 'learning',
117 124 'label' => __( 'Learning', 'desktop-mode' ),
@@ -119,8 +126,9 @@
119 126 'icon' => 'dashicons-welcome-learn-more',
120 127 'color' => '#43a047',
121 128 'layout' => 'tile',
122 129 'order' => 20,
130 + 'requires' => array( 'sensei-lms/sensei-lms.php' ),
123 131 ),
124 132 array(
125 133 'id' => 'publishing',
126 134 'label' => __( 'Publishing', 'desktop-mode' ),
@@ -142,8 +150,13 @@
142 150 * resolves a built-in's. The three shipped entries deliberately
143 151 * carry neither, because the client already has their token lists
144 152 * and duplicating them here would be two places to keep in step.
145 153 *
154 + * `requires` is the one field that stays on this side: a list of
155 + * plugin basenames that must be active for the template to be
156 + * offered at all. Unset it on a shipped entry to be offered that
157 + * desk whatever is installed.
158 + *
146 159 * @param array[] $presets List of preset definitions.
147 160 */
148 161 $presets = apply_filters( 'openstation_workspace_presets', $presets );
149 162
@@ -152,8 +165,11 @@
152 165 }
153 166
154 167 $clean = array();
155 168 foreach ( $presets as $preset ) {
169 + if ( ! openstation_workspace_preset_requirements_met( $preset ) ) {
170 + continue;
171 + }
156 172 $entry = openstation_sanitize_workspace_preset( $preset );
157 173 if ( null !== $entry ) {
158 174 $clean[] = $entry;
159 175 }
@@ -158,8 +174,43 @@
158 174 $clean[] = $entry;
159 175 }
160 176 }
161 177 return $clean;
178 +}
179 +
180 +/**
181 + * Whether the plugins a template is built around are active here.
182 + *
183 + * `requires` is a list of plugin basenames — `woocommerce/woocommerce.php`,
184 + * the same string `is_plugin_active()` takes — and every one of them has
185 + * to be active or the template is not offered at all. A template that
186 + * names none is always offered.
187 + *
188 + * The gate runs after the `openstation_workspace_presets` filter, so a
189 + * site that wants a template anyway can unset its `requires` there.
190 + *
191 + * @param mixed $preset Raw preset definition.
192 + * @return bool Whether the template may be offered.
193 + */
194 +function openstation_workspace_preset_requirements_met( $preset ) {
195 + if ( ! is_array( $preset ) || empty( $preset['requires'] ) || ! is_array( $preset['requires'] ) ) {
196 + return true;
197 + }
198 + if ( ! function_exists( 'is_plugin_active' ) ) {
199 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
200 + }
201 + foreach ( $preset['requires'] as $plugin ) {
202 + if ( ! is_string( $plugin ) ) {
203 + continue;
204 + }
205 + // A basename is a path, so the traversal characters go — the
206 + // value is compared against `active_plugins`, never opened.
207 + $plugin = str_replace( '..', '', substr( preg_replace( '#[^A-Za-z0-9_./-]#', '', $plugin ), 0, 256 ) );
208 + if ( '' === $plugin || ! is_plugin_active( $plugin ) ) {
209 + return false;
210 + }
211 + }
212 + return true;
162 213 }
163 214
164 215 /**
165 216 * Sanitizes a launch entry's `place` — where a window goes, as