PluginProbe ʕ •ᴥ•ʔ
Kubio AI Page Builder / trunk
Kubio AI Page Builder vtrunk
2.9.1 2.9.0 2.8.6 2.8.5 2.8.4 2.8.3 2.8.2 2.8.1 trunk 1.0.0 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.9.0 2.0.0 2.1.1 2.1.2 2.1.3 2.2.0 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.5 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.6.2 2.6.3 2.6.5 2.6.6 2.6.7 2.7.0 2.7.1 2.7.2 2.7.3 2.8.0
kubio / lib / api / colibri.php
kubio / lib / api Last commit date
multilanguage 1 year ago recommendations 1 month ago colibri.php 1 day ago contact-form.php 1 year ago entity.php 4 years ago get-body-class.php 1 year ago get-classic-page-template.php 1 year ago get-page-query.php 1 year ago get-page-title.php 1 year ago get-post-content.php 1 year ago get-post-styles.php 1 year ago index.php 1 year ago kubio-cloud.php 1 year ago page-templates.php 4 years ago save-template-parts-filter.php 1 year ago subscribe-form.php 4 years ago typekit.php 4 years ago update-settings-flags.php 1 year ago
colibri.php
478 lines
1 <?php
2
3 use IlluminateAgnostic\Arr\Support\Arr;
4 use Kubio\Flags;
5 use Kubio\Core\Utils;
6
7 add_action(
8 'rest_api_init',
9 function () {
10 $namespace = 'kubio/v1';
11
12 // the ui for these two is behind getShowInternalFeatures( 'cloud' ) in with-save-block-preset.js,
13 // keep the routes behind the same flag so they are not registered at all on a public build
14 if ( Utils::getShowInternalFeatures( 'cloud' ) ) {
15 register_rest_route(
16 $namespace,
17 '/snippet',
18 array(
19 'methods' => 'POST',
20 'callback' => 'kubio_save_block_snippet',
21 'permission_callback' => function () {
22 return current_user_can( 'edit_theme_options' );
23 },
24 )
25 );
26
27 register_rest_route(
28 $namespace,
29 '/snippet/update',
30 array(
31 'methods' => 'POST',
32 'callback' => 'kubio_update_block_snippet',
33 'permission_callback' => function () {
34 return current_user_can( 'edit_theme_options' );
35 },
36 )
37 );
38 }
39
40 // same as above, the ui for these two is behind the kubio_is_ai_site_editor backend data
41 // in guest-ai-generated-sites-editor/utils.js, which is this very same check
42 if ( Utils::getIsAISiteEditor() ) {
43 register_rest_route(
44 $namespace,
45 '/update-generated-ai-site-content',
46 array(
47 'methods' => 'POST',
48 'callback' => 'kubio_update_generated_ai_site_content',
49 'permission_callback' => function () {
50 return current_user_can( 'edit_theme_options' );
51 },
52 )
53 );
54 register_rest_route(
55 $namespace,
56 '/update-generated-ai-site-content-by-style',
57 array(
58 'methods' => 'POST',
59 'callback' => 'kubio_update_generated_ai_site_content_by_style',
60 'permission_callback' => function () {
61 return current_user_can( 'edit_theme_options' );
62 },
63 )
64 );
65 }
66 }
67 );
68
69
70 /**
71 * API callback for saving a snippet; It creates a zip archive with the html template, the screenshot and the assets.
72 * Also sends the zip archive to Kubio cloud.
73 *
74 * @param WP_REST_Request $request
75 * @return void
76 */
77 function kubio_save_block_snippet( WP_REST_Request $request ) {
78 if ( ! class_exists( 'ZipArchive' ) ) {
79 wp_send_json_error( __( 'Zip Export not supported.', 'kubio' ) );
80 }
81
82 $name = $request->get_param( 'name' );
83 $category = $request->get_param( 'category' );
84 $snippet = $request->get_param( 'snippet' );
85 $screenshot = $request->get_param( 'screenshot' );
86 $global_data = $request->get_param( 'globalData' );
87 $zip_path = get_temp_dir() . $name . '.zip';
88
89 $screenshot_ext = explode( ';base64,', $screenshot );
90 $screenshot_ext = explode( 'data:image/', $screenshot_ext[0] );
91
92 if ( empty( $screenshot_ext[1] ) ) {
93 wp_send_json_error( __( 'Bad screenshot.', 'kubio' ) );
94 }
95
96 // allow only letters, numbers, underscore, dashe and space characters.
97 if ( preg_match( '/[^A-Za-z0-9_ \-]/', $name ) || strlen( $name ) > 100 ) {
98 wp_send_json_error( __( 'Bad name.', 'kubio' ) );
99 }
100
101 $zip = kubio_create_snippet_zip( $zip_path, $snippet, $screenshot, $global_data );
102
103 $apiKey = Flags::get( 'kubio_cloud_api_key' );
104
105 $request_url = add_query_arg(
106 array(
107 'filename' => $name,
108 'category_id' => $category,
109 'block' => $snippet[0],
110 ),
111 Utils::getSnippetsURL( '/save' )
112 );
113
114 $response = wp_remote_post(
115 $request_url,
116 array(
117 'headers' => array(
118 'X-Authorization' => $apiKey,
119 'accept' => 'application/json',
120 'content-type' => 'application/binary',
121 ),
122 'body' => file_get_contents( $zip_path ),
123 )
124 );
125
126 $response_code = wp_remote_retrieve_response_code( $response );
127
128 if ( 200 !== $response_code ) {
129 $errorMessage = wp_remote_retrieve_body( $response );
130 wp_send_json_error( $errorMessage , $response_code);
131 }
132
133 $body = wp_remote_retrieve_body( $response );
134
135 wp_send_json_success( json_decode( $body ) );
136 }
137
138 function kubio_update_block_snippet( WP_REST_Request $request ) {
139 if ( ! class_exists( 'ZipArchive' ) ) {
140 wp_send_json_error( __( 'Zip Export not supported.', 'kubio' ) );
141 }
142
143 $id = $request->get_param( 'id' );
144 $name = $request->get_param( 'name' );
145 $category = $request->get_param( 'category' );
146 $snippet = $request->get_param( 'snippet' );
147 $screenshot = $request->get_param( 'screenshot' );
148 $global_data = $request->get_param( 'globalData' );
149
150 $zip_path = get_temp_dir() . $name . '.zip';
151
152 if ( empty( $id ) ) {
153 wp_send_json_error( __( 'No id.', 'kubio' ) );
154 }
155
156 // allow only letters, numbers, underscore, dashe and space characters.
157 if ( preg_match( '/[^A-Za-z0-9_ \-]/', $name ) || strlen( $name ) > 100 ) {
158 wp_send_json_error( __( 'Bad name.', 'kubio' ) );
159 }
160
161 $zip = kubio_create_snippet_zip( $zip_path, $snippet, $screenshot, $global_data );
162
163 $apiKey = Flags::get( 'kubio_cloud_api_key' );
164
165 $args = array(
166 'filename' => $name,
167 'category_id' => $category,
168 'block' => $snippet[0],
169
170 );
171
172 $request_url = add_query_arg(
173 $args,
174 Utils::getSnippetsURL( '/' . $id . '/update' )
175 );
176
177 $response = wp_remote_post(
178 $request_url,
179 array(
180 'headers' => array(
181 'X-Authorization' => $apiKey,
182 'accept' => 'application/json',
183 'content-type' => 'application/binary',
184 ),
185 'body' => file_get_contents( $zip_path ),
186 )
187 );
188
189 $response_code = wp_remote_retrieve_response_code( $response );
190
191 if ( 200 !== $response_code ) {
192 $errorMessage = wp_remote_retrieve_body($response);
193 wp_send_json_error( $errorMessage, $response_code);
194 }
195
196 $body = wp_remote_retrieve_body( $response );
197
198 wp_send_json_success( json_decode( $body ) );
199 }
200
201 /**
202 * This function creates a temporary zip file for the given snippet.
203 *
204 * @param $path
205 * @param $snippet
206 * @param $screenshot_data
207 * @return false|ZipArchive
208 */
209 function kubio_create_snippet_zip( $path, $snippet, $screenshot_data, $global_data ) {
210 // create the zip archive and start adding.
211 $zip = new ZipArchive();
212 if ( true !== $zip->open( $path, ZipArchive::CREATE | ZipArchive::OVERWRITE ) ) {
213 wp_send_json_error( __( 'Unable to open export file (archive) for writing.', 'kubio' ) );
214 }
215
216 // handle the screenshot data and add it to the zip
217 if ( preg_match( '/^data:image\/(\w+);base64,/', $screenshot_data, $screenshot_type ) ) {
218 $screenshot_data = substr( $screenshot_data, strpos( $screenshot_data, ',' ) + 1 );
219 $screenshot_type = strtolower( $screenshot_type[1] ); // jpg, png, gif
220 if ( ! in_array( $screenshot_type, array( 'jpg', 'jpeg', 'gif', 'png' ) ) ) {
221 return false;
222 }
223
224 $screenshot_data = str_replace( ' ', '+', $screenshot_data );
225 $screenshot_data = base64_decode( $screenshot_data );
226
227 $zip->addFromString( 'screenshot.' . $screenshot_type, $screenshot_data );
228 }
229
230 $zip->addFromString( 'global.json', json_encode( $global_data, JSON_PRETTY_PRINT ) );
231
232 // from now on we search assets from the template, and we save them in the archive.
233 //$zip->addEmptyDir( 'assets' );
234
235 // search for media files by urls.
236 $upload_settings = wp_get_upload_dir();
237 $pattern = '#' . str_replace( '/', '\/', $upload_settings['baseurl'] ) . '(.*?)"#';
238 $pattern = str_replace( ':', '\:', $pattern );
239 preg_match_all( $pattern, json_encode( $snippet, JSON_UNESCAPED_SLASHES ), $matches );
240
241 $uploaded_files = array();
242
243 if ( ! empty( $matches ) ) {
244 $uploaded_files = $matches[1];
245 }
246
247 // search media files by id.
248 $uploaded_files = kubio_parse_blocks_for_media_id_atts_and_stack( $snippet, $uploaded_files );
249
250 foreach ( $uploaded_files as $uploaded_file ) {
251 $file_path = $upload_settings['basedir'] . $uploaded_file;
252
253 if ( file_exists( $file_path ) ) {
254 $file = file_get_contents( $file_path );
255 $new_path = wp_normalize_path( 'assets' . $uploaded_file );
256 $zip->addFromString( $new_path, $file );
257 }
258 }
259
260 // at last, save the snippet template and close the zip archive.
261 $parsed = str_replace( $upload_settings['baseurl'], '{{snippet_url}}', json_encode( $snippet, JSON_UNESCAPED_SLASHES ) );
262 $zip->addFromString( 'template.json', $parsed );
263
264 $zip->close();
265 return $zip;
266 }
267
268
269 /**
270 * This function searches for attributes that hold media files and adds them to the $uploaded_files stack.
271 *
272 * @param $block
273 * @param $uploaded_files
274 * @return mixed
275 */
276 function kubio_parse_blocks_for_media_id_atts_and_stack( $block, $uploaded_files = false ) {
277 // $block[0] is the block name.
278 $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block[0] );
279
280 if ( ! empty( $block_type->supports['kubio'] ) ) {
281 $assets_importer_map = Arr::get( $block_type->supports['kubio'], 'assetsURLImporterMap', array() );
282
283 if ( ! empty( $assets_importer_map ) ) {
284 $id_attr = '';
285 foreach ( $assets_importer_map as $url_attr => $import_map ) {
286 $id_attr = Arr::get( $import_map, 'assetIdToAttr' );
287 }
288
289 // $block[1] holds the attributes
290 $id = $block[1][ $id_attr ];
291
292 if ( ! empty( $id ) ) {
293 $url = wp_get_attachment_url( $id );
294 $parsed = wp_parse_url( $url );
295 $new_path = str_replace( '/wp-content/uploads', '', $parsed['path'] );
296 if ( ! in_array( $new_path, $uploaded_files ) ) {
297 $uploaded_files[] = $new_path;
298 }
299 }
300 }
301 }
302
303 // at $block['2'] there should be an array of blocks as innerBlocks.
304 if ( ! empty( $block['2'] ) ) {
305 $uploaded_files = kubio_parse_blocks_for_media_id_atts_and_stack( $block['2'][0], $uploaded_files );
306 }
307
308 return $uploaded_files;
309 }
310 function kubio_update_generated_ai_site_content( WP_REST_Request $request) {
311
312 $params = $request->get_param( 'params' );
313
314 $apiKey = Flags::get( 'kubio_cloud_api_key' );
315
316 $request_url = Utils::getCloudURL( '/api/generated-ai-sites/update-content' );
317
318
319 $response = wp_remote_post(
320 $request_url,
321 array(
322 'headers' => array(
323 'X-Authorization' => $apiKey,
324 'accept' => 'application/json',
325 'content-type' => 'application/json',
326 ),
327 'body' => json_encode(
328 array(
329 'params' => array_merge($params,
330 array(
331 'testing' => true
332 )
333 ),
334 )
335 ),
336 )
337 );
338
339 $response_code = wp_remote_retrieve_response_code( $response );
340
341 if ( 200 !== $response_code ) {
342 $errorMessage = wp_remote_retrieve_body($response);
343 wp_send_json_error( $errorMessage, $response_code );
344 }
345
346 $body = wp_remote_retrieve_body( $response );
347
348 wp_send_json_success( json_decode( $body ) );
349 }
350 function kubio_update_generated_ai_site_content_by_style( WP_REST_Request $request) {
351
352 $params = $request->get_param( 'params' );
353
354 $apiKey = Flags::get( 'kubio_cloud_api_key' );
355
356 $request_url = Utils::getCloudURL( '/api/generated-ai-sites-by-style/update-content' );
357
358 $response = wp_remote_post(
359 $request_url,
360 array(
361 'headers' => array(
362 'X-Authorization' => $apiKey,
363 'accept' => 'application/json',
364 'content-type' => 'application/json',
365 ),
366 'body' => json_encode(
367 array(
368 'params' => array_merge($params,
369 array(
370 'testing' => true
371 )
372 ),
373 )
374 ),
375 )
376 );
377
378 $response_code = wp_remote_retrieve_response_code( $response );
379
380 if ( 200 !== $response_code ) {
381 $errorMessage = wp_remote_retrieve_body($response);
382 wp_send_json_error( $errorMessage, $response_code );
383 }
384
385 $body = wp_remote_retrieve_body( $response );
386
387 wp_send_json_success( json_decode( $body ) );
388 }
389
390 function kubio_get_installed_theme() {
391 $themes = wp_get_themes();
392 $kubio_themes = array( 'kubio', 'elevate-wp' );
393 $intersect = array_values( array_intersect( array_keys( $themes ), $kubio_themes ) );
394 $theme = Arr::get( $intersect, 0, null );
395 return $theme;
396 }
397
398 function kubio_enable_theme( WP_REST_Request $data ) {
399 switch_theme( $data['name'] );
400 return wp_send_json( array( 'switched' => $data['name'] ) );
401 }
402
403 function kubio_colibri_data_export_done() {
404
405 // copy menus location from colibri to kubio;
406 $colibri_options = get_option( 'theme_mods_colibri-wp', array() );
407 $kubio_options = get_option( 'theme_mods_kubio', array() );
408
409 $colibri_locations = Arr::get( $colibri_options, 'nav_menu_locations', array() );
410 $kubio_locations = Arr::get( $kubio_options, 'nav_menu_locations', array() );
411
412 $locations_map = array(
413 'header-menu' => 'header-menu',
414 'footer-menu' => 'footer-menu',
415 'footer-menu-1' => 'footer-menu-secondary',
416 'header-menu-1' => 'header-menu-secondary',
417 );
418
419 foreach ( $colibri_locations as $location => $menu ) {
420 $location = Arr::get( $locations_map, $location, $location );
421 $kubio_locations[ $location ] = $menu;
422 }
423
424 Arr::set( $kubio_options, 'nav_menu_locations', $kubio_locations );
425
426 if ( $theme = kubio_get_installed_theme() ) {
427 update_option( "theme_mods_{$theme}", $kubio_options );
428 switch_theme( $theme );
429
430 flush_rewrite_rules();
431 update_option( 'theme_switched', false );
432 }
433
434 wp_send_json_success();
435 }
436
437 function kubio_colibri_data_export() {
438
439 $theme = kubio_get_installed_theme();
440
441 if ( $theme ) {
442 ob_clean();
443
444 // templates are created with colibri-wp theme on kubio activation //
445 foreach ( get_block_templates( array(), 'wp_template' ) as $template ) {
446 wp_set_post_terms( $template->wp_id, $theme, 'wp_theme' );
447 }
448
449 echo wp_json_encode(
450 \ExtendBuilder\export_colibri_data(
451 array( 'exclude_generated' => true ),
452 false
453 )
454 );
455 switch_theme( $theme );
456 } else {
457 wp_send_json_error(
458 array(
459 'error' => 'kubio-not-installed',
460 )
461 );
462 }
463 }
464
465 add_filter(
466 'colibri_page_builder/get_partial_details',
467 function ( $data ) {
468 $post = get_post( $data['id'] );
469 $new_data = array(
470 'title' => $post->post_title,
471 'page_template' => $post->page_template,
472 'parent' => $post->post_parent,
473 );
474 return array_merge( $data, $new_data );
475 },
476 100
477 );
478