PluginProbe
WDesignKit – AI Templates, Widget Builder & MCP Workflow / 2.7.0
WDesignKit – AI Templates, Widget Builder & MCP Workflow v2.7.0
2.7.0 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 All 129 releases
wdesignkit / includes / admin / import / class-wdkit-import-team-images.php

class-wdkit-import-team-images.php in WDesignKit – AI Templates, Widget Builder & MCP Workflow 2.7.0, at includes/admin/import/class-wdkit-import-team-images.php

161 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Team-library image sourcing.
4 *
5 * ── How the browser does it ─────────────────────────────────────────────────
6 *
7 * import_loader.js#replace_ai_team(), per team group found in the template:
8 *
9 * team_type === 'testimonial' → folder_id 14 (a fixed collection)
10 * otherwise → folder_id = site_obj.site_category_id
11 * (the industry the visitor picked)
12 * img_type = group.img_type (wdkitai_team_library on the widget)
13 * count = number of slots in the group, defaulting to 5
14 *
15 * It then POSTs `select_team_img` and, if the library returns fewer images than there are
16 * slots, cycles the returned list until every slot has one.
17 *
18 * This class reproduces that decision-making and delegates the cloud call to
19 * Wdkit_Import_temp_Ajax::wdkit_team_images_data() — the same method the AJAX action now
20 * uses, so there is one implementation of the request.
21 *
22 * Returned URLs are treated as untrusted: they are handed to Wdkit_Import_Media::sideload(),
23 * which SSRF-validates before fetching.
24 *
25 * @package Wdesignkit
26 * @since 2.6.5
27 */
28
29 if ( ! defined( 'ABSPATH' ) ) {
30 exit;
31 }
32
33 if ( ! class_exists( 'Wdkit_Import_Team_Images' ) ) {
34
35 /**
36 * Team image resolver.
37 */
38 class Wdkit_Import_Team_Images {
39
40 /**
41 * Fixed collection used for testimonial portraits.
42 *
43 * Mirrors the literal `folder_id = 14` in replace_ai_team().
44 */
45 const TESTIMONIAL_FOLDER_ID = 14;
46
47 /**
48 * Default number of images requested when a group has no slots counted.
49 */
50 const DEFAULT_COUNT = 5;
51
52 /**
53 * Fetch replacement photos for one team group.
54 *
55 * @param array $group {img_type, team_type, imgs} from Wdkit_Import_Media.
56 * @param array $context Validated import context.
57 * @return string[] Library URLs, empty when unavailable.
58 */
59 public static function fetch( $group, $context ) {
60 $group = is_array( $group ) ? $group : array();
61
62 $team_type = ! empty( $group['team_type'] ) ? $group['team_type'] : 'testimonial';
63 $img_type = ! empty( $group['img_type'] ) ? $group['img_type'] : 'default';
64 $count = ! empty( $group['imgs'] ) && is_array( $group['imgs'] ) ? count( $group['imgs'] ) : self::DEFAULT_COUNT;
65
66 $folder_id = ( 'testimonial' === $team_type )
67 ? (string) self::TESTIMONIAL_FOLDER_ID
68 : (string) ( isset( $context['site_category_id'] ) ? $context['site_category_id'] : '' );
69
70 /* No industry chosen and not a testimonial group → nothing sensible to ask for.
71 * The template keeps its own photos, which is the safe outcome. */
72 if ( '' === $folder_id ) {
73 return array();
74 }
75
76 $token = self::token();
77
78 $images = self::request( $folder_id, $img_type, $count, $token );
79
80 /**
81 * Filter the team images resolved for one group.
82 *
83 * Kept so a caller can substitute a source without touching the runner. Values are
84 * still SSRF-validated downstream, so a filter cannot introduce an unsafe fetch.
85 *
86 * @param string[] $images Resolved URLs.
87 * @param array $group Team group.
88 * @param array $context Validated context.
89 */
90 $images = apply_filters( 'wdkit_import_runner_team_images', $images, $group, $context );
91
92 return is_array( $images ) ? array_values( array_filter( $images, 'is_string' ) ) : array();
93 }
94
95 /**
96 * Ask the cloud for a collection's images.
97 *
98 * @param string $folder_id Collection id.
99 * @param string $img_type Collection variant.
100 * @param int $count How many are needed.
101 * @param string $token Cloud token.
102 * @return string[]
103 */
104 private static function request( $folder_id, $img_type, $count, $token ) {
105 if ( ! class_exists( 'Wdkit_Import_temp_Ajax' ) ) {
106 return array();
107 }
108
109 $instance = Wdkit_Import_temp_Ajax::get_instance();
110
111 if ( ! method_exists( $instance, 'wdkit_team_images_data' ) ) {
112 return array();
113 }
114
115 $result = $instance->wdkit_team_images_data( $folder_id, $img_type, $count, $token );
116
117 if ( empty( $result['success'] ) || empty( $result['data']['images'] ) ) {
118 return array();
119 }
120
121 $images = $result['data']['images'];
122
123 return is_array( $images ) ? array_values( array_filter( $images, 'is_string' ) ) : array();
124 }
125
126 /**
127 * The cloud token for this site.
128 *
129 * Reuses the resolver every other cloud ability uses, so the PHP runner authenticates
130 * exactly as the rest of the plugin does and no new credential is introduced.
131 *
132 * @return string
133 */
134 private static function token() {
135 if ( function_exists( 'wdkit_kit_import_resolve_token' ) ) {
136 $token = (string) wdkit_kit_import_resolve_token();
137 if ( '' !== $token ) {
138 return $token;
139 }
140 }
141
142 if ( class_exists( 'Wdkit_Import_Remote' ) && method_exists( 'Wdkit_Import_Remote', 'poll_token' ) ) {
143 $token = (string) Wdkit_Import_Remote::poll_token();
144 if ( '' !== $token ) {
145 return $token;
146 }
147 }
148
149 if ( function_exists( 'wdesignkit_mcp_find_auth_session' ) ) {
150 $session = wdesignkit_mcp_find_auth_session();
151
152 if ( ! empty( $session['found'] ) && ! empty( $session['data']['token'] ) ) {
153 return (string) $session['data']['token'];
154 }
155 }
156
157 return '';
158 }
159 }
160 }
161