PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.3.1
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.3.1
3.7.5 3.7.4 3.7.3 3.7.2 1-final 3.7.1 3.7.0 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.10 All 111 releases
templately / includes / API / AIContent.php

AIContent.php in Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! 3.3.1, at includes/API/AIContent.php

404 lines 13.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Templately AI Content Importer
5 *
6 * @package Templately
7 * @since 1.0.0
8 */
9
10 namespace Templately\API;
11
12 use Error;
13 use Templately\Utils\Helper;
14 use WP_REST_Request;
15 use Templately\Core\Importer\Utils\Utils;
16 use Templately\Core\Importer\Utils\AIUtils;
17
18 class AIContent extends API {
19 private $endpoint = 'ai-content';
20 private $dev_mode = false;
21
22
23 /**
24 * AIContent constructor.
25 *
26 * @param string $file File path.
27 * @param array $settings Settings.
28 */
29 public function __construct() {
30 $this->dev_mode = (defined('TEMPLATELY_DEV') && TEMPLATELY_DEV) || (defined('IMPORT_DEBUG') && IMPORT_DEBUG);
31
32 parent::__construct();
33
34 }
35
36 public function _permission_check(WP_REST_Request $request) {
37 $this->request = $request;
38 $process_id = $this->get_param('process_id');
39
40 $_route = $request->get_route();
41 if ('/templately/v1/ai-content/ai-update' === $_route || '/templately/v1/ai-content/ai-update-preview' === $_route) {
42 if (empty($process_id)) {
43 return $this->error('invalid_id', __('Invalid ID.', 'templately'), 'calculate_credit', 400);
44 }
45
46 // Check AI process data using API key-based storage
47 $ai_process_data = AIUtils::get_ai_process_data();
48 if (is_array($ai_process_data) && !empty($ai_process_data[$process_id])) {
49 return true;
50 }
51
52 return (bool) Helper::get_matched_session_data($process_id);
53 }
54
55 return parent::permission_check($request);
56 }
57
58
59 public function register_routes() {
60 // $this->get( $this->endpoint . '/calculate-credit', [ $this, 'calculate_credit' ] );
61 $this->post($this->endpoint . '/modify-content', [$this, 'modify_content']);
62 $this->post($this->endpoint . '/ai-update', [$this, 'ai_update']);
63 $this->post($this->endpoint . '/ai-update-preview', [$this, 'ai_update_preview']);
64 // die(rest_url( 'templately/v1/ai-content/ai-update' ));
65 }
66
67 public function calculate_credit() {
68 $pack_id = $this->get_param('pack_id');
69
70 return [
71 'status' => 'success',
72 'data' => [
73 'availableCredit' => 100,
74 ],
75 ];
76
77 if (empty($pack_id)) {
78 return $this->error('invalid_id', __('Invalid ID.', 'templately'), 'calculate_credit', 400);
79 }
80
81 $response = wp_remote_get($this->get_api_url("ai/calculate-credit/pack/$pack_id"), [
82 'timeout' => 30,
83 'headers' => [
84 'Accept' => 'application/json',
85 'Content-Type' => 'application/json',
86 'Authorization' => 'Bearer ' . $this->api_key,
87 'x-templately-ip' => Helper::get_ip(),
88 'x-templately-url' => home_url('/'),
89 'x-templately-version' => TEMPLATELY_VERSION,
90 ]
91 ]);
92
93
94 // return $response;
95 if (is_wp_error($response)) {
96 return $this->error('request_failed', __('Request failed.', 'templately'), 'calculate_credit', 500, $response);
97 }
98
99 $body = wp_remote_retrieve_body($response);
100 $data = json_decode($body, true);
101 // error status is ok
102 if (! is_array($data) || ! isset($data['status'])) {
103 return $this->error('invalid_response', __('Invalid response.', 'templately'), 'calculate_credit', 500);
104 }
105
106
107 return $data;
108 }
109
110 public function modify_content() {
111 add_filter('wp_redirect', '__return_false', 999);
112 set_time_limit(3 * MINUTE_IN_SECONDS);
113 ini_set('max_execution_time', 3 * MINUTE_IN_SECONDS);
114
115 $pack_id = $this->get_param('pack_id');
116 $isBusinessNichesNew = $this->get_param('isBusinessNichesNew', false);
117 $ai_page_ids = $this->get_param('ai_page_ids', [], null);
118 $content_ids = $this->get_param('content_ids', [], null);
119 $session_id = $this->get_param('session_id'); // Add session_id parameter
120 $preview_pages = $this->get_param('preview_pages', [], null);
121 $platform = $this->get_param('platform');
122
123 // ai content fields
124 $name = $this->get_param('name');
125 $category = $this->get_param('category');
126 $description = $this->get_param('description');
127 $email = $this->get_param('email');
128 $contactNumber = $this->get_param('contactNumber');
129 $businessAddress = $this->get_param('businessAddress');
130 $openingHour = $this->get_param('openingHour');
131
132 if (empty($pack_id)) {
133 return $this->error('invalid_id', __('Invalid ID.', 'templately'), 'modify_content', 400);
134 }
135 if (empty($category)) {
136 return $this->error('invalid_prompt', __('Invalid prompt.', 'templately'), 'modify_content', 400);
137 }
138 if (empty($content_ids) && empty($preview_pages)) {
139 return $this->error('invalid_content_ids', __('Invalid content ids.', 'templately'), 'modify_content', 400);
140 }
141 if (empty($platform)) {
142 return $this->error('invalid_platform', __('Invalid platform.', 'templately'), 'modify_content', 400);
143 }
144
145
146 // $response = get_transient( '__templately_ai_process_id' );
147
148 // if(empty($response)) {
149 $response = wp_remote_post($this->get_api_url("ai/modify-content/pack"), [
150 'timeout' => 15 * MINUTE_IN_SECONDS,
151 'headers' => [
152 'Accept' => 'application/json',
153 'Content-Type' => 'application/json',
154 'Authorization' => 'Bearer ' . $this->api_key,
155 'x-templately-ip' => Helper::get_ip(),
156 'x-templately-url' => home_url('/'),
157 'x-templately-version' => TEMPLATELY_VERSION,
158 'x-templately-session-id' => $session_id,
159 ],
160 'body' => json_encode([
161 'business_name' => $name,
162 'business_niches' => $category,
163 'prompt' => $description,
164 'email' => $email,
165 'phone' => $contactNumber,
166 'address' => $businessAddress,
167 'openingHour' => $openingHour,
168 'pack_id' => $pack_id,
169 'content_ids' => $content_ids,
170 'platform' => $platform,
171 'preview_pages' => $preview_pages,
172 'callback' => defined('TEMPLATELY_CALLBACK') ? TEMPLATELY_CALLBACK . '/wp-json/templately/v1/ai-content/ai-update' : rest_url('templately/v1/ai-content/ai-update'),
173 ]),
174 ]);
175
176 // set_transient( '__templately_ai_process_id', $response, 60 * 60 * 24 * 30 );
177 // }
178
179 $bk_ai_business_niches = get_option('templately_ai_business_niches', []);
180 if (!empty($business_niches) && $isBusinessNichesNew && ! in_array($business_niches, $bk_ai_business_niches)) {
181 $bk_ai_business_niches[] = $business_niches;
182 update_option('templately_ai_business_niches', $bk_ai_business_niches, false);
183 }
184
185 // return $response;
186 if (is_wp_error($response)) {
187 error_log(print_r($response, true));
188 return $this->error('request_failed', __('Request failed.', 'templately'), 'modify_content', 500, $response->additional_data);
189 }
190
191 $body = wp_remote_retrieve_body($response);
192 $data = json_decode($body, true);
193 // error status is ok, if status is error then return as is
194 if (! is_array($data) || ! isset($data['status'])) {
195 return $this->error('invalid_response', __('Invalid response.', 'templately'), 'modify_content', 500, $data);
196 }
197
198 // "{"status":"success","message":"The content is being generated in the queue","process_id":"01JRQQD39GNWTNF18EWF8YH0BG-271838-pack-408"}"
199 if (isset($data['status']) && $data['status'] === 'success' && isset($data['process_id'])) {
200 $process_id = $data['process_id'];
201
202 // Save templates to files if available using the common function
203 if (!empty($data['templates']) && is_array($data['templates'])) {
204 foreach ($data['templates'] as $content_id => $template_data) {
205 // Decode template if it's base64 encoded
206 if (! empty($template_data) && base64_decode($template_data, true) !== false) {
207 $data['templates'][$content_id] = base64_decode($template_data);
208 }
209
210 if (!empty($template_data)) {
211 Helper::save_template_to_file(
212 $process_id,
213 $content_id,
214 $template_data,
215 $ai_page_ids,
216 true, // Always use preview mode for AI content workflow
217 isset($template_data['isSkipped']) ? $template_data['isSkipped'] : false
218 );
219 }
220 }
221 }
222
223 $ai_process_data[$process_id] = [
224 'name' => $name,
225 'category' => $category,
226 'description' => $description,
227 'email' => $email,
228 'contactNumber' => $contactNumber,
229 'businessAddress' => $businessAddress,
230 'openingHour' => $openingHour,
231 'process_id' => $process_id,
232 'pack_id' => $pack_id,
233 'ai_page_ids' => $ai_page_ids,
234 'ai_preview_ids' => $preview_pages,
235 'content_ids' => $content_ids,
236 'platform' => $platform,
237 'api_key' => $this->api_key,
238 'session_id' => $session_id, // Store session_id for coordination
239 ];
240
241 // Update using API key-based storage with automatic count-based cleanup
242 AIUtils::update_ai_process_data($ai_process_data);
243
244 return [
245 'status' => 'success',
246 'message' => __('The content is being generated in the queue', 'templately'),
247 'process_id' => $process_id,
248 'templates' => !empty($data['templates']) ? $data['templates'] : null,
249 'is_local_site' => !empty($data['is_local_site']) ? $data['is_local_site'] : null,
250 ];
251 }
252
253 return $data;
254 }
255
256 public function ai_update() {
257 add_filter('wp_redirect', '__return_false', 999);
258
259 $template = $this->get_param('template');
260 $process_id = $this->get_param('process_id');
261 $template_id = $this->get_param('template_id');
262 $content_id = $this->get_param('content_id');
263 $type = $this->get_param('type');
264 $isSkipped = $this->get_param('isSkipped', false);
265 $credit_cost = $this->request->get_param('credit_cost');
266
267 error_log('process_id: ' . $process_id);
268
269 // Handle credit cost updates separately
270 if ($this->request->has_param('credit_cost')) {
271 $processed_pages = get_option("templately_ai_processed_pages", []);
272 $processed_pages[$process_id] = $processed_pages[$process_id] ?? [];
273 $processed_pages[$process_id]['credit_cost'] = $credit_cost;
274 update_option("templately_ai_processed_pages", $processed_pages, false);
275
276 return [
277 'status' => 'success',
278 'data' => [
279 'process_id' => $process_id,
280 'credit_cost' => $credit_cost,
281 ],
282 ];
283 }
284
285 // Always use preview mode for AI content workflow
286 // Get AI process data using API key-based storage
287 $ai_process_data = AIUtils::get_ai_process_data();
288
289 if (empty($ai_process_data[$process_id]['ai_page_ids'])) {
290 return $this->error('invalid_process_id', __('Invalid process id.', 'templately'), 'ai-content/ai-update', 400);
291 }
292
293 $ai_page_ids = $ai_process_data[$process_id]['ai_page_ids'];
294
295 // Use the common helper function to save the template (always preview mode)
296 $result = Helper::save_template_to_file(
297 $process_id,
298 $content_id,
299 $template,
300 $ai_page_ids,
301 true, // Always use preview mode
302 $isSkipped
303 );
304
305 if(is_wp_error($result)){
306 return $result;
307 }
308
309 // Return the result from the helper function
310 if (isset($result['status']) && $result['status'] === 'success') {
311 return $result;
312 }
313
314 // Return error if the helper function failed
315 return $result;
316 }
317
318 public function ai_update_preview() {
319 add_filter('wp_redirect', '__return_false', 999);
320
321 $template = $this->get_param('templates'); // Now expects an array with content_id as keys
322 $process_id = $this->get_param('process_id');
323 $isSkipped = $this->get_param('isSkipped', false);
324 $error = $this->get_param('error', null);
325
326 error_log('process_id: ' . $process_id);
327
328 if (!empty($isSkipped) || !empty($error)) {
329 // Update AI process data with error using API key-based storage
330 $ai_process_data = AIUtils::get_ai_process_data();
331 if (isset($ai_process_data[$process_id])) {
332 $ai_process_data[$process_id]['preview_error'] = $error;
333 AIUtils::update_ai_process_data($ai_process_data);
334 }
335 wp_send_json_error([
336 'status' => 'error',
337 'message' => $error,
338 ]);
339 }
340
341 // Validate template parameter is an array
342 if (!is_array($template) || empty($template)) {
343 return $this->error('invalid_template', __('Template must be a non-empty array with content_id as keys.', 'templately'), 'ai-content/ai-update-preview', 400);
344 }
345
346 // Always use preview mode for AI content workflow
347 // Get AI process data using API key-based storage
348 $ai_process_data = AIUtils::get_ai_process_data();
349
350 if (empty($ai_process_data[$process_id]['ai_page_ids'])) {
351 return $this->error('invalid_process_id', __('Invalid process id.', 'templately'), 'ai-content/ai-update-preview', 400);
352 }
353
354 $ai_page_ids = $ai_process_data[$process_id]['ai_page_ids'];
355 $results = [];
356 $success_count = 0;
357 $error_count = 0;
358
359 // Process each content_id/template pair
360 foreach ($template as $content_id => $template_data) {
361 // Use the common helper function to save the template (always preview mode)
362 $result = Helper::save_template_to_file(
363 $process_id,
364 $content_id,
365 $template_data,
366 $ai_page_ids,
367 true, // Always use preview mode
368 $isSkipped
369 );
370
371 $results[$content_id] = $result;
372
373 // Track success/error counts
374 if (isset($result['status']) && $result['status'] === 'success') {
375 $success_count++;
376 } else {
377 $error_count++;
378 }
379 }
380
381 // Return consolidated response
382 $overall_status = $error_count === 0 ? 'success' : ($success_count === 0 ? 'error' : 'partial_success');
383
384 // Note: No cleanup needed with API key-based storage and count-based management
385
386 return [
387 'status' => $overall_status,
388 'message' => sprintf(
389 __('Processed %d templates: %d successful, %d failed.', 'templately'),
390 count($template),
391 $success_count,
392 $error_count
393 ),
394 ];
395 }
396
397
398
399 private function get_api_url($end_point): string {
400 $dev_mode = defined('TEMPLATELY_DEV') && TEMPLATELY_DEV;
401 return $dev_mode ? "https://app.templately.dev/api/v2/" . $end_point : "https://app.templately.com/api/v2/" . $end_point;
402 }
403 }
404