PluginProbe
WDesignKit – AI Templates, Widget Builder & MCP Workflow / trunk
WDesignKit – AI Templates, Widget Builder & MCP Workflow vtrunk
2.6.6 2.6.5 2.6.4 2.6.3 2.6.2 2.6.1 2.6.0 2.5.5 2.5.4 2.5.3 2.5.2 2.5.1 2.5.0 2.4.0 2.3.3 2.3.2 2.3.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 All 128 releases
← All changes | wdesignkit.php +348 -4 2.6.2trunk View file →
@@ -1,10 +1,10 @@
1 1 <?php
2 2 /**
3 - * Plugin Name: WDesignKit - Elementor & Gutenberg Starter Templates, Patterns, Cloud Workspace & Widget Builder
3 + * Plugin Name: WDesignKit - AI Templates, Widget Builder & MCP Workflow
4 4 * Plugin URI: https://wdesignkit.com/
5 - * Description: Your All-in-One solution for effortless WordPress website creation and collaboration. With over 1,000+ Elementor and WordPress website templates, a library of 100+ pre-made widgets for Elementor, Gutenberg Blocks, and Bricks, along with a cloud workspace for collaboration and more.
6 - * Version: 2.6.2
5 + * Description: 3000+ Elementor & Gutenberg Templates, AI Templates, AI Widget Builder, AI Code Snippets, MCP Workflow, Cloud Workspace & 220+ Widgets Library.
6 + * Version: 2.6.6
7 7 * Author: POSIMYTH
8 8 * Author URI: https://posimyth.com/
9 9 * Text Domain: wdesignkit
10 10 * Domain Path: /languages
@@ -35,9 +35,9 @@
35 35 );
36 36 return;
37 37 }
38 38
39 -define( 'WDKIT_VERSION', '2.6.2' );
39 +define( 'WDKIT_VERSION', '2.6.6' );
40 40 define( 'WDKIT_FILE', __FILE__ );
41 41 define( 'WDKIT_PATH', plugin_dir_path( __FILE__ ) );
42 42 define( 'WDKIT_PBNAME', plugin_basename( __FILE__ ) );
43 43 define( 'WDKIT_BDNAME', basename( dirname( __FILE__ )) );
@@ -53,6 +53,350 @@
53 53 /** Widget Builder path*/
54 54 define( 'WDKIT_SERVER_PATH', wp_upload_dir()['baseurl'] . '/wdesignkit' );
55 55 define( 'WDKIT_BUILDER_PATH', wp_upload_dir()['basedir'] . '/wdesignkit' );
56 56 define( 'WDKIT_GET_SITE_URL', get_site_url() );
57 +
58 +/*
59 + * POSIMYTH Analytics SDK.
60 + *
61 + * Every POSIMYTH plugin bundles its own copy of the shared classes and registers it here rather than
62 + * requiring them directly. The loader collects every registered copy and, at plugins_loaded priority
63 + * 0 — before any consumer, which run at priority 10 — loads the files from the NEWEST one, as
64 + * declared by that copy's version.php. Requiring them directly instead would let load order decide,
65 + * and an older sibling would silently define the shared classes for the whole suite.
66 + *
67 + * Keep the copy in sync with .dev/sync-posimyth-sdk.py in Nexter Extension — never hand-edit
68 + * anything under includes/posimyth-sdk/ except this product's own class-posimyth-tracker-wdk.php,
69 + * which the sync script does not touch.
70 + */
71 +require_once WDKIT_PATH . 'includes/posimyth-sdk/posimyth-sdk-loader.php';
72 +posimyth_sdk_register( WDKIT_PATH . 'includes/posimyth-sdk' );
73 +
74 +/**
75 + * Whether this install has been rebranded.
76 + *
77 + * Standalone rather than a method on the survey config class, because the tracker needs the same
78 + * answer on front-end and cron requests, and that class carries eight inline reason icons that have
79 + * no business being compiled outside the Plugins screen.
80 + *
81 + * Only the five rebranding keys count. Plain UI preferences stored in the same option must not
82 + * suppress the tracker — that was the lesson from The Plus Addons, where they did.
83 + *
84 + * @since 2.6.4
85 + *
86 + * @return bool
87 + */
88 +function wdkit_posimyth_is_white_labelled() {
89 + $label = get_option( 'wkit_white_label', array() );
90 +
91 + if ( ! is_array( $label ) ) {
92 + return false;
93 + }
94 +
95 + foreach ( array( 'plugin_name', 'plugin_desc', 'plugin_logo', 'developer_name', 'website_url' ) as $key ) {
96 + if ( ! empty( $label[ $key ] ) && is_scalar( $label[ $key ] ) && '' !== trim( (string) $label[ $key ] ) ) {
97 + return true;
98 + }
99 + }
100 +
101 + return false;
102 +}
103 +
104 +add_action(
105 + 'plugins_loaded',
106 + function () {
107 + /*
108 + * A rebranded install no longer bails here.
109 + *
110 + * It used to: the tracker, the consent notice and the posimyth_consent_wdk AJAX handler were
111 + * all skipped, which meant the Settings panel's Data Sharing card had no handler to save to
112 + * and had to be hidden entirely. Sharing now follows the white-label CRITERIA instead of the
113 + * mere fact of rebranding — the feature stays available and consent-gated as everywhere else,
114 + * while every user-visible string uses the reseller's own plugin name (see $wl_name below) and
115 + * the POSIMYTH docs link is dropped wherever help_link is set.
116 + *
117 + * Consent still governs collection: on a rebranded site, as on any other, nothing is sent
118 + * until someone turns the switch on.
119 + */
120 + $wl_label = get_option( 'wkit_white_label', array() );
121 + $wl_label = is_array( $wl_label ) ? $wl_label : array();
122 + $wl_name = ! empty( $wl_label['plugin_name'] ) && is_scalar( $wl_label['plugin_name'] ) ? trim( (string) $wl_label['plugin_name'] ) : '';
123 + $wl_name = '' !== $wl_name ? $wl_name : 'WDesignKit';
124 + // help_link is the reseller's "hide POSIMYTH documentation links" switch — honoured here the
125 + // same way the editor stylesheets honour it.
126 + $wl_hide_docs = ! empty( $wl_label['help_link'] );
127 + // "Hide all Plugin Updates related News?" — the reseller's switch for plugin-authored admin
128 + // notices. The consent bar is one, so it is not registered at all when this is on. The tracker
129 + // and the Settings panel's Data Sharing card are unaffected: consent can still be given there,
130 + // it is simply never asked for unprompted on a rebranded dashboard.
131 + $wl_hide_notice = ! empty( $wl_label['plugin_news'] );
132 +
133 + // Shared base already loaded by the SDK loader at priority 0; the subclass is ours alone.
134 + require_once WDKIT_PATH . 'includes/posimyth-sdk/class-posimyth-tracker-wdk.php';
135 +
136 + if ( class_exists( 'Posimyth_Tracker_WDK' ) ) {
137 + /*
138 + * Registers activate / deactivate / weekly-heartbeat hooks and the cron, all consent-gated,
139 + * plus the template-import counter. NOT inside the is_admin() gate below: the weekly
140 + * heartbeat fires from wp-cron.php, which is not an admin request.
141 + */
142 + Posimyth_Tracker_WDK::init();
143 + }
144 +
145 + if ( ! is_admin() ) {
146 + return;
147 + }
148 +
149 + /*
150 + * Guarded on class_exists rather than assumed: the loader requires the three shared files as a
151 + * set, but a sibling plugin requiring one of them directly, or shipping an older SDK revision,
152 + * can leave these classes undefined. An unguarded `new` would fatal on every admin page load.
153 + */
154 + // Also guarded on Posimyth_Tracker_WDK: this block reads its OPT_IN_OPTION constant and
155 + // passes send_first_ping as a callback below. class-posimyth-tracker-wdk.php is required
156 + // unconditionally above, but declaring the class can itself fail if a sibling POSIMYTH
157 + // plugin's newer SDK copy won the loader with a diverged Posimyth_Tracker_Base signature —
158 + // the exact multi-plugin case posimyth_sdk_register() exists for. Without this guard, that
159 + // leaves Posimyth_Tracker_WDK undefined and the ::OPT_IN_OPTION reference below fatals every
160 + // wp-admin request (Consent_Notice is only constructed when is_admin()), locking the admin
161 + // out of the dashboard with no way to deactivate via the UI.
162 + if ( class_exists( 'Posimyth_Consent_Notice' ) && class_exists( 'Posimyth_Tracker_WDK' ) ) {
163 + /*
164 + * WDesignKit's OWN consent key and OWN suite — not Nexter's.
165 + *
166 + * Nexter Extension and Nexter Blocks share one answer because they are one brand with one
167 + * dashboard. WDesignKit is a separate product on its own site with its own dashboard, so it
168 + * asks separately and stores separately. A site running both sees two notices, one per
169 + * product — that is the intent, not a bug: consenting to share Nexter data is not consenting
170 + * to share WDesignKit data.
171 + *
172 + * The constructor registers its own hooks; nothing else needs the instance.
173 + */
174 + $wdkit_consent_notice = new Posimyth_Consent_Notice(
175 + array(
176 + // The reseller's own product name on a rebranded install, 'WDesignKit' otherwise.
177 + 'plugin_name' => $wl_name,
178 + 'plugin_slug' => 'wdesignkit',
179 + 'opt_in_option' => Posimyth_Tracker_WDK::OPT_IN_OPTION,
180 + 'ajax_action' => 'posimyth_consent_wdk',
181 + 'installed_option' => 'posimyth_wdk_first_use_at',
182 + 'tracker_cb' => array( 'Posimyth_Tracker_WDK', 'send_first_ping' ),
183 + // The SDK's suite_name default is 'Nexter', and it is what the notice prints instead
184 + // of plugin_name once more than one product registers. WDesignKit is its own suite of
185 + // one, so its suite name is simply its own name.
186 + 'suite_name' => $wl_name,
187 + 'suite_key' => 'wdk_suite',
188 + // WDesignKit's own docs, not nexterwp.com. UTM matches the shape the SDK uses for its
189 + // own default, so this notice is distinguishable from other places the docs are linked.
190 + 'docs_url' => WDKIT_DOCUMENT . 'data-sharing/?utm_source=wpbackend&utm_medium=admin&utm_campaign=datasharingnotice',
191 + // Legacy hook only, for host stylesheets. The SDK stylesheet keys off `posi-*`.
192 + 'css_prefix' => 'wdkit',
193 + // Passed explicitly. One copy of the notice class serves every active POSIMYTH plugin,
194 + // so a product that passes nothing is painted by whatever that copy defaults to.
195 + // --wdkit_blk_shade, matching the deactivation dialog. The SDK feeds this into
196 + // --posi-accent, so the icon, left border and both buttons follow from this one value.
197 + 'accent' => '#020202',
198 + )
199 + );
200 +
201 + /*
202 + * "Hide all Plugin Updates related News?" is on: keep the object, drop only the banner.
203 + *
204 + * The notice is constructed either way because its constructor is what registers
205 + * wp_ajax_posimyth_consent_wdk — the handler the Settings panel's Data Sharing toggle saves
206 + * through. Skipping construction removed the banner AND broke that toggle on exactly this
207 + * configuration. Unhooking render() suppresses the banner while leaving the handler live, so
208 + * consent is never asked for unprompted but can still be given from Settings.
209 + */
210 + if ( $wl_hide_notice ) {
211 + remove_action( 'admin_notices', array( $wdkit_consent_notice, 'render' ) );
212 + }
213 + }
214 +
215 + /*
216 + * Reseller has "hide documentation links" on: drop the notice's "See what's shared" anchor.
217 + *
218 + * Done in CSS rather than by passing an empty docs_url, because the SDK's render() prints the
219 + * anchor unconditionally and would emit href="" — and includes/posimyth-sdk/ is sync-managed,
220 + * so the notice class itself must not be edited here. Scoped to THIS product's notice, so a
221 + * sibling POSIMYTH plugin's notice on the same screen keeps its own link.
222 + *
223 + * Hooked on the same handle the SDK attaches its own inline CSS to, at a later priority so
224 + * this rule always follows and wins on equal specificity.
225 + */
226 + if ( $wl_hide_docs ) {
227 + add_action(
228 + 'admin_enqueue_scripts',
229 + function () {
230 + wp_add_inline_style( 'wp-admin', '.posi-consent-notice.posi-consent--wdesignkit .posi-notice-text a { display: none; }' );
231 + },
232 + 20
233 + );
234 + }
235 +
236 + /*
237 + * WDesignKit's skin for the shared deactivation dialog — design only.
238 + *
239 + * Enqueued from here, on the Plugins screen alone, because that is the only screen the dialog
240 + * can open on. It overrides the SDK's base rules through `.posi-deact-p-wdesignkit`, the parent
241 + * class that file documents for exactly this purpose, so includes/posimyth-sdk/ stays untouched
242 + * and a sibling POSIMYTH product's dialog keeps its own look.
243 + */
244 + add_action(
245 + 'admin_enqueue_scripts',
246 + function ( $hook ) {
247 + if ( 'plugins.php' !== $hook ) {
248 + return;
249 + }
250 +
251 + $skin_rel = 'assets/css/dashborad/wdkit-deactivate-survey.css';
252 + $skin_abs = WDKIT_PATH . $skin_rel;
253 +
254 + /*
255 + * Versioned by mtime, not WDKIT_VERSION.
256 + *
257 + * WDKIT_VERSION only moves on release, so every edit to this file inside one version
258 + * ships under a URL the browser already has cached — the stale copy keeps being served
259 + * and the change looks like it did not apply. Falls back to the plugin version if the
260 + * file is unreadable.
261 + */
262 + $skin_ver = file_exists( $skin_abs ) ? (string) filemtime( $skin_abs ) : WDKIT_VERSION;
263 +
264 + wp_enqueue_style(
265 + 'wdkit-deactivate-survey',
266 + WDKIT_URL . $skin_rel,
267 + array(),
268 + $skin_ver
269 + );
270 +
271 + /*
272 + * Adds the dialog's close button. Injected rather than printed because the markup is
273 + * sync-managed; see the file header. Versioned by mtime for the same reason as the
274 + * stylesheet above.
275 + */
276 + $close_rel = 'assets/js/admin/wdkit-deactivate-survey.js';
277 + $close_abs = WDKIT_PATH . $close_rel;
278 + $close_ver = file_exists( $close_abs ) ? (string) filemtime( $close_abs ) : WDKIT_VERSION;
279 +
280 + wp_enqueue_script(
281 + 'wdkit-deactivate-survey',
282 + WDKIT_URL . $close_rel,
283 + array(),
284 + $close_ver,
285 + true
286 + );
287 +
288 + wp_localize_script(
289 + 'wdkit-deactivate-survey',
290 + 'wdkitDeactSurvey',
291 + array(
292 + 'close_label' => __( 'Close', 'wdesignkit' ),
293 + )
294 + );
295 + }
296 + );
297 +
298 + if ( ! class_exists( 'Posimyth_Deactivation_Survey' ) ) {
299 + return;
300 + }
301 +
302 + /*
303 + * Required lazily, inside the is_admin() gate: the config carries eight inline reason icons
304 + * that have no business being compiled on a front-end request.
305 + */
306 + require_once WDKIT_INCLUDES . 'admin/notices/class-wdkit-deactivate-survey.php';
307 +
308 + new Posimyth_Deactivation_Survey( Wdkit_Deactivate_Survey::args() );
309 + }
310 +);
311 +
312 +/**
313 + * Developer tool: re-arm the data-sharing consent notice.
314 + *
315 + * The notice is deliberately hard to see twice — quiet for 2 days after install, snoozed 30 days by
316 + * "Dismiss", silenced for good by "Allow", and never rendered while sharing is already on. That is
317 + * right for users and leaves no way to review the bar again, so this resets those four gates.
318 + *
319 + * Three conditions, all required:
320 + *
321 + * - WP_DEBUG. This never loads on a production site, so it cannot be reached on a real install
322 + * however the URL is guessed.
323 + * - The same capability the notice itself answers for — network admin on multisite, since the
324 + * consent is one answer per install.
325 + * - A valid nonce. The reset writes site options, and a bare GET would let a crafted link flip
326 + * another admin's consent state from anywhere on the web.
327 + *
328 + * Use the "Reset Data Sharing Notice" item added to the admin bar, which carries the nonce. There is
329 + * deliberately no hand-typeable URL: that was the earlier QA shortcut this replaces.
330 + *
331 + * @since 2.6.4
332 + */
333 +if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
334 +
335 + add_action(
336 + 'admin_bar_menu',
337 + function ( $bar ) {
338 + $cap = is_multisite() ? 'manage_network_options' : 'manage_options';
339 +
340 + if ( ! current_user_can( $cap ) ) {
341 + return;
342 + }
343 +
344 + $bar->add_node(
345 + array(
346 + 'id' => 'wdkit-reset-consent',
347 + 'title' => __( 'Reset Data Sharing Notice', 'wdesignkit' ),
348 + 'href' => wp_nonce_url( admin_url( 'index.php?wdkit_reset_consent=1' ), 'wdkit_reset_consent' ),
349 + 'parent' => 'top-secondary',
350 + )
351 + );
352 + },
353 + 100
354 + );
355 +
356 + add_action(
357 + 'admin_init',
358 + function () {
359 + if ( empty( $_GET['wdkit_reset_consent'] ) ) {
360 + return;
361 + }
362 +
363 + $cap = is_multisite() ? 'manage_network_options' : 'manage_options';
364 +
365 + if ( ! current_user_can( $cap ) ) {
366 + return;
367 + }
368 +
369 + check_admin_referer( 'wdkit_reset_consent' );
370 +
371 + // Site options, matching how the SDK stores them: one consent per install, not per blog.
372 + delete_site_option( 'posi_consent_dismissed_wdk_suite' );
373 + delete_site_option( 'posi_consent_snoozed_until_wdk_suite' );
374 + delete_site_option( 'posi_consent_grace_start_wdk_suite' );
375 +
376 + // Sharing has to be off for the bar to render at all — the notice never asks for
377 + // permission that has already been granted.
378 + if ( class_exists( '\Posimyth_Tracker_WDK' ) ) {
379 + update_site_option( \Posimyth_Tracker_WDK::OPT_IN_OPTION, 0 );
380 + }
381 +
382 + /*
383 + * grace_period_ends() re-stamps the start it just found missing, so deleting that option is
384 + * not enough on its own — the window has to be zeroed for THIS request too. admin_init runs
385 + * before admin_notices, so the filter is in place before the notice decides.
386 + */
387 + add_filter( 'posimyth_consent_notice_grace_seconds', '__return_zero' );
388 +
389 + add_action(
390 + 'admin_notices',
391 + function () {
392 + echo '<div class="notice notice-success is-dismissible"><p>' .
393 + esc_html__( 'Data-sharing consent reset. The notice should appear below.', 'wdesignkit' ) .
394 + '</p></div>';
395 + },
396 + 5
397 + );
398 + }
399 + );
400 +}
57 401
58 402 require WDKIT_PATH . 'includes/class-wdkit-wdesignkit.php';