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 | includes/admin/class-api.php +119 -1 2.6.4trunk View file →
@@ -3052,8 +3052,34 @@
3052 3052 }
3053 3053 }
3054 3054 }
3055 3055
3056 + /**
3057 + * Fires after a template has been imported from the cloud.
3058 + *
3059 + * WDesignKit's templates live in the cloud, so nothing local records that an import
3060 + * happened — there is no post type, no option, nothing to count after the fact. This is the
3061 + * only moment the information exists.
3062 + *
3063 + * @since 2.6.4
3064 + *
3065 + * @param string $kind 'single' or 'kit'.
3066 + * @param string $builder Builder the template was imported for, e.g. 'elementor'.
3067 + * @param int $count How many templates this import brought in.
3068 + */
3069 + // Only a completed import counts. The cloud's failure shape for this endpoint family sets
3070 + // content => 'error' (see the sibling check in wdkit_import_kit_template() above) — that is
3071 + // non-empty, so the previous `||` fired the counter on failed imports too. Require success
3072 + // AND an absent/non-'error' content instead.
3073 + if ( ! empty( $response['success'] ) && ( ! isset( $response['content'] ) || 'error' !== $response['content'] ) ) {
3074 + do_action(
3075 + 'wdkit_template_imported',
3076 + 'import_kit_template' === $api_type ? 'kit' : 'single',
3077 + isset( $_POST['builder'] ) ? sanitize_key( wp_unslash( $_POST['builder'] ) ) : '',
3078 + 1
3079 + );
3080 + }
3081 +
3056 3082 wp_send_json( $response );
3057 3083 wp_die();
3058 3084 }
3059 3085
@@ -3880,8 +3906,28 @@
3880 3906 $output['description'] = $response['description'];
3881 3907 $output['data'] = $result;
3882 3908 $output['success'] = $response['success'];
3883 3909
3910 + // Counts the IMPORT ACTION, not what it brought in. A kit import always counts as 1 kit,
3911 + // no matter how many blocks/pages that kit contains — confirmed live: a single gutenberg
3912 + // kit import recorded total=680, kinds.kit=680, because $template_ids for that call was a
3913 + // 680-element array of the kit's own blocks and count( $template_ids ) counted every one of
3914 + // them. A page-kit's *size* is not tracking's concern; "was a kit imported" is.
3915 + //
3916 + // The 'single' branch keeps a defensive fallback for the one shape this endpoint's own
3917 + // $template_ids reliably takes when it is not a kit — a single {id, name, slug, thumb...}
3918 + // object — where count() would likewise count JSON keys instead of "1 template imported".
3919 + if ( ! empty( $output['success'] ) ) {
3920 + $is_kit = ( '' !== $website_kit );
3921 + $import_count = $is_kit ? 1 : ( isset( $template_ids['id'] ) ? 1 : ( is_array( $template_ids ) ? count( $template_ids ) : 1 ) );
3922 + do_action(
3923 + 'wdkit_template_imported',
3924 + $is_kit ? 'kit' : 'single',
3925 + sanitize_key( $builder ),
3926 + $import_count
3927 + );
3928 + }
3929 +
3884 3930 wp_send_json( $output );
3885 3931 wp_die();
3886 3932 }
3887 3933
@@ -4366,8 +4412,15 @@
4366 4412 Tpgb_Library()->remove_backend_dir_files();
4367 4413 }
4368 4414
4369 4415 clean_post_cache( $inserted_post );
4416 +
4417 + // This whole method imports exactly one section per call — unlike
4418 + // wdkit_import_template()/wdkit_import_kit_template(), it never fired this hook
4419 + // at all, so single-section imports (Header/Footer/CTA/etc., a primary import
4420 + // path per the Template Type sidebar) were invisible to tracking entirely.
4421 + do_action( 'wdkit_template_imported', 'single', sanitize_key( $editor ), 1 );
4422 +
4370 4423 wp_send_json(
4371 4424 array(
4372 4425 $temp_id => $temp_detail,
4373 4426 'description' => 'Yay! Your Section has been Successfully Imported.',
@@ -4505,8 +4558,12 @@
4505 4558 }
4506 4559
4507 4560 \Elementor\Plugin::$instance->files_manager->clear_cache();
4508 4561
4562 + // See the matching note in the Gutenberg branch above — this method never
4563 + // fired the tracking hook for either editor.
4564 + do_action( 'wdkit_template_imported', 'single', 'elementor', 1 );
4565 +
4509 4566 wp_send_json(
4510 4567 array(
4511 4568 $temp_id => $temp_detail,
4512 4569 'content' => $temp_con,
@@ -5040,12 +5097,73 @@
5040 5097 }
5041 5098
5042 5099 $response = json_decode( wp_json_encode( $response['data'] ), true );
5043 5100
5101 + $this->wdkit_cache_cloud_usage( $response );
5102 +
5044 5103 wp_send_json( $response );
5045 5104 wp_die();
5046 5105 }
5047 5106
5107 + /**
5108 + * Caches the storage / credit figures this response carried.
5109 + *
5110 + * This handler is the ONLY place those numbers ever exist on the site: the cloud endpoint
5111 + * authenticates with a user token that only a logged-in dashboard request carries, so the
5112 + * analytics heartbeat — which runs on cron with no user at all — can never fetch them itself.
5113 + * Caching them here is what lets Posimyth_Tracker_WDK report them, and it reports the cache's
5114 + * age alongside so a stale reading is recognisable as one.
5115 + *
5116 + * Field names are probed rather than assumed: the cloud has renamed these before, and the
5117 + * licence ability already carries six spellings of its own key field for the same reason. An
5118 + * unrecognised shape simply caches nothing rather than storing a wrong number.
5119 + *
5120 + * Only the figures are kept. No token, no account id, no email — the analytics consent copy
5121 + * promises non-sensitive data only, and this is read by the payload builder.
5122 + *
5123 + * @since 2.6.4
5124 + *
5125 + * @param mixed $data Decoded `data` object from the credits endpoint.
5126 + * @return void
5127 + */
5128 + private function wdkit_cache_cloud_usage( $data ) {
5129 + if ( ! is_array( $data ) ) {
5130 + return;
5131 + }
5132 +
5133 + $pick = static function ( $source, array $fields ) {
5134 + foreach ( $fields as $field ) {
5135 + if ( isset( $source[ $field ] ) && is_numeric( $source[ $field ] ) ) {
5136 + return (float) $source[ $field ];
5137 + }
5138 + }
5139 + return null;
5140 + };
5141 +
5142 + $usage = array(
5143 + 'storage_used' => $pick( $data, array( 'used_storage', 'storage_used', 'used_space' ) ),
5144 + 'storage_total' => $pick( $data, array( 'total_storage', 'storage_total', 'storage', 'total_space' ) ),
5145 + 'credit_used' => $pick( $data, array( 'used_credit', 'credit_used', 'used_credits' ) ),
5146 + 'credit_total' => $pick( $data, array( 'total_credit', 'credit_total', 'credits', 'real_credit' ) ),
5147 + );
5148 +
5149 + $usage = array_filter(
5150 + $usage,
5151 + static function ( $value ) {
5152 + return null !== $value;
5153 + }
5154 + );
5155 +
5156 + if ( empty( $usage ) ) {
5157 + return;
5158 + }
5159 +
5160 + $usage['cached_at'] = gmdate( 'Y-m-d H:i:s' );
5161 +
5162 + // Not autoloaded: read once a week by the heartbeat, never on a front-end request.
5163 + update_option( 'wdkit_cloud_usage', $usage, false );
5164 + }
5165 +
5048 5166 public function wdkit_nxt_thembuilder_reset() {
5049 5167 $post_id = isset( $_POST['post_id'] ) ? sanitize_text_field( $_POST['post_id'] ) : '';
5050 5168 $sections_layout = get_post_meta( $post_id, 'nxt-hooks-layout-sections', true );
5051 5169
@@ -5776,9 +5894,9 @@
5776 5894 'template' => isset( $get_setting['template'] ) ? $get_setting['template'] : true,
5777 5895 'gutenberg_builder' => isset( $get_setting['gutenberg_builder'] ) ? $get_setting['gutenberg_builder'] : true,
5778 5896 'gutenberg_core_builder' => isset( $get_setting['gutenberg_core_builder'] ) ? $get_setting['gutenberg_core_builder'] : false,
5779 5897 'elementor_builder' => isset( $get_setting['elementor_builder'] ) ? $get_setting['elementor_builder'] : true,
5780 - 'bricks_builder' => isset( $get_setting['bricks_builder'] ) ? $get_setting['bricks_builder'] : false,
5898 + 'bricks_builder' => isset( $get_setting['bricks_builder'] ) ? $get_setting['bricks_builder'] : true,
5781 5899 'gutenberg_template' => isset( $get_setting['gutenberg_template'] ) ? $get_setting['gutenberg_template'] : true,
5782 5900 'elementor_template' => isset( $get_setting['elementor_template'] ) ? $get_setting['elementor_template'] : true,
5783 5901 'code_snippet' => isset( $get_setting['code_snippet'] ) ? $get_setting['code_snippet'] : true,
5784 5902 'cross_copy_paste' => isset( $get_setting['cross_copy_paste'] ) ? $get_setting['cross_copy_paste'] : false,