PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.9.1
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.9.1
2.13.0 2.13.1 2.12.0 2.11.1 2.11.0 2.10.0 2.9.0 2.7.4 2.7.5 2.7.6 2.7.7 2.8.0 2.8.1 2.9.1 trunk 1.0 1.0-beta1 1.0-beta2 1.0-beta3 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 All 80 releases
ablocks / includes / ajax / demo-import.php

demo-import.php in aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder 2.9.1, at includes/ajax/demo-import.php

394 lines 11.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace ABlocks\Ajax;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 use ABlocks\Classes\AbstractAjaxHandler;
10 use ABlocks\Classes\Sanitizer;
11 use ABlocks\Helper;
12 use ABlocks\import\CustomizerImporter;
13 use ABlocks\import\ThemeOptions\CodeStar;
14 use ABlocks\import\ThemeOptions\Redux;
15 use ABlocks\import\WidgetImporter;
16
17 class DemoImport extends AbstractAjaxHandler {
18
19 public function __construct() {
20 $this->actions = array(
21 'get_demo_list' => array(
22 'callback' => array( $this, 'get_demo_list' ),
23 'fields' => array(
24 'type' => 'string',
25 'cost_type' => 'string',
26 'page' => 'integer',
27 'per_page' => 'integer',
28 'category' => 'string',
29 'dev' => 'string',
30 'q' => 'string',
31 )
32 ),
33 'get_single_demo' => array(
34 'callback' => array( $this, 'get_single_demo' ),
35 'fields' => array(
36 'id' => 'integer',
37 'with_images' => 'string',
38 )
39 ),
40 'get_demo_categories' => array(
41 'callback' => array( $this, 'get_demo_categories' ),
42 'fields' => array(
43 'type' => 'string',
44 )
45 ),
46 'get_theme_demos' => array(
47 'callback' => array( $this, 'get_theme_demos' ),
48 ),
49 'check_dependencies' => array(
50 'callback' => array( $this, 'check_dependencies' ),
51 'fields' => array(
52 'dependencies' => 'array|string',
53 )
54 ),
55 'install_and_active' => array(
56 'callback' => array( $this, 'install_and_active' ),
57 'fields' => array(
58 'dependency' => 'array|string',
59 )
60 ),
61 'import_template' => array(
62 'callback' => array( $this, 'import_template' ),
63 'fields' => array(
64 'file_url' => 'string',
65 'customizer_file_url' => 'string',
66 'widget_file_url' => 'string',
67 'codestar_file_url' => 'string',
68 'redux_options' => 'json',
69 'with_images' => 'boolean',
70 )
71 ),
72 );
73 }
74
75 /**
76 * Get demo list data from database, if not exists, then get & store data from API.
77 *
78 * @param array $data Query Data for API.
79 *
80 * @return void
81 */
82 public function get_demo_list( array $data ) {
83 $args = [
84 'type' => $data['type'] ?? 'pattern',
85 'cost_type' => $data['cost_type'] ?? 'all',
86 'page' => $data['page'] ?? 1,
87 ];
88
89 if ( isset( $data['category'] ) ) {
90 $args['category'] = $data['category'];
91 }
92
93 if ( isset( $data['dev'] ) ) {
94 $args['dev'] = $data['dev'];
95 }
96
97 if ( isset( $data['q'] ) ) {
98 $args['q'] = $data['q'];
99 }
100
101 if ( isset( $data['per_page'] ) ) {
102 $args['per_page'] = $data['per_page'];
103 }
104
105 $hash = md5( wp_json_encode( $args ) );
106 $key = "ablocks_demo_$hash";
107 $has_response = get_transient( $key );
108 if ( $has_response ) {
109 wp_send_json_success( $has_response );
110 }
111
112 $url = 'https://' . ABLOCKS_TEMPLATE_LIB_HOST . '/wp-json/ablocks_server/v1/ablocks';
113 $url = add_query_arg( $args, $url );
114 $this->handle_list_response( $url, $key );
115 }
116
117 /**
118 * Get single demo data from database, if not exists, then get & store data from API.
119 *
120 * @param array $data inside data `id` is required.
121 *
122 * @return void
123 */
124 public function get_single_demo( array $data ) {
125 if ( ! $data['id'] ) {
126 wp_send_json_error( __( 'id is required.', 'ablocks' ) );
127 }
128 $id = absint( $data['id'] );
129 $with_images = isset( $data['with_images'] ) && true === (bool) $data['with_images'];
130
131 $key = 'ablocks_demo_item_' . $id;
132 $has_response = get_transient( $key );
133 if ( $has_response ) {
134 if ( $with_images && ! isset( $has_response['remote_images_parsed'] ) ) {
135 $has_response['content'] = Helper::parse_remote_images( $has_response['content'] );
136 $has_response['remote_images_parsed'] = true;
137 set_transient( $key, $has_response, WEEK_IN_SECONDS );
138 }
139 unset( $has_response['remote_images_parsed'] );
140 wp_send_json_success( $has_response );
141 }
142
143 $url = 'https://' . ABLOCKS_TEMPLATE_LIB_HOST . '/wp-json/ablocks_server/v1/ablocks/' . $id;
144 $response = wp_safe_remote_get( $url );
145 if ( is_wp_error( $response ) ) {
146 wp_send_json_error( $response->get_error_message() );
147 }
148
149 $response_code = wp_remote_retrieve_response_code( $response );
150 $response = wp_remote_retrieve_body( $response );
151 $response = json_decode( $response, true );
152 if ( $response_code !== 200 ) {
153 wp_send_json_error( $response );
154 }
155
156 $response = $response['data'];
157 if ( $with_images ) {
158 $content = $response['content'] ?? null;
159 if ( $content ) {
160 $response['content'] = Helper::parse_remote_images( wp_unslash( $content ) );
161 $response['remote_images_parsed'] = true;
162 }
163 }
164 set_transient( $key, $response, WEEK_IN_SECONDS );
165 unset( $response['remote_images_parsed'] );
166 wp_send_json_success( $response );
167 }
168
169 /**
170 * Get demo category list data from database, if not exists, then get & store data from API.
171 *
172 * @param array $data Query Data for Category list API.
173 *
174 * @return void
175 */
176 public function get_demo_categories( array $data ) {
177 $type = $data['type'] ?? 'pattern';
178 $key = "ablocks_demo_categories_$type";
179 $has_response = get_transient( $key );
180 if ( $has_response ) {
181 wp_send_json_success( $has_response );
182 }
183
184 $url = 'https://' . ABLOCKS_TEMPLATE_LIB_HOST . '/wp-json/ablocks_server/v1/categories';
185 $url = add_query_arg( 'type', $type, $url );
186 $this->handle_list_response( $url, $key );
187 }
188
189 /**
190 * Get theme demos.
191 *
192 * @return void
193 */
194 public function get_theme_demos() {
195 $demo_config = Helper::get_theme_demo_config();
196 if ( ! $demo_config ) {
197 wp_send_json_error([
198 'message' => 'Current theme demo isn\'t configured.',
199 ]);
200 }
201
202 $demos = $demo_config['demos'];
203 $categories = [];
204 foreach ( $demos as &$demo ) {
205 $demo_categories = [];
206 foreach ( $demo['categories'] as $category ) {
207 if ( is_array( $category ) ) {
208 $categories[] = $category;
209 $demo_categories[] = $category;
210 } else {
211 $demo_category = [
212 'label' => ucfirst( $category ),
213 'slug' => str_replace( ' ', '-', trim( $category ) ),
214 ];
215 $categories[] = $demo_category;
216 $demo_categories[] = $demo_category;
217 }
218 }
219 $demo['categories'] = $demo_categories;
220 }
221
222 $preloaded_categories = array_map(fn ( $category) => is_array( $category ) ? $category : [
223 'label' => ucfirst( $category ),
224 'slug' => str_replace( ' ', '-', trim( $category ) ),
225 ], $demo_config['preloaded_demo_category']);
226
227 $categories_slugs = array_map( fn ( $category) => $category['slug'], $categories );
228 foreach ( $preloaded_categories as $preloaded_category ) {
229 if ( ! in_array( $preloaded_category['slug'], $categories_slugs, true ) ) {
230 $categories[] = $preloaded_category;
231 }
232 }
233
234 wp_send_json_success( array(
235 'categories' => $categories,
236 'preloaded_demo' => $demo_config['preloaded_demo'],
237 'preloaded_demo_categories' => $preloaded_categories,
238 'demos' => $demos,
239 ) );
240 }
241
242 /**
243 * Check dependencies before importing pattern/page/template.
244 *
245 * @param array $data Dependency Data.
246 *
247 * @return void
248 */
249 public function check_dependencies( array $data ) {
250 if ( ! isset( $data['dependencies'] ) ) {
251 return;
252 }
253
254 $dependencies = Sanitizer::sanitize_array_field( $data['dependencies'] );
255 foreach ( $dependencies as $index => $dependency ) {
256 $type = 'check_' . ( $dependency['type'] ?? 'plugin' );
257 $status = Helper::$type( $dependency['slug'] );
258 $dependencies[ $index ]['status'] = $status;
259 if ( isset( $dependency['id'] ) ) {
260 $dependencies[ $index ]['id'] = (int) $dependency['id'];
261 }
262 }
263
264 wp_send_json_success( $dependencies );
265 }
266
267 /**
268 * Install and active theme/plugin from ajax request.
269 *
270 * @param array $data post-data.
271 *
272 * @return void
273 */
274 public function install_and_active( array $data ) {
275 if ( ! isset( $data['dependency'] ) ) {
276 return;
277 }
278 $dependency = Sanitizer::sanitize_array_field( $data['dependency'] );
279 $method = 'install_and_active_' . ( $dependency['type'] ?? 'plugin' );
280 $activated = Helper::$method( $dependency['slug'] );
281 if ( is_wp_error( $activated ) ) {
282 wp_send_json_error(array(
283 'message' => $activated->get_error_message(),
284 ));
285 }
286
287 wp_send_json_success();
288 }
289
290 /**
291 * Import template from file url.
292 *
293 * @param array $data Import data.
294 *
295 * @return void
296 */
297 public function import_template( array $data ) {
298 if ( ! isset( $data['file_url'] ) ) {
299 return;
300 }
301
302 $file_url = $data['file_url'];
303 $content_file_path = Helper::remote_to_tmp_file( $file_url );
304
305 $customizer_file_url = $data['customizer_file_url'] ?? '';
306 $customizer_file_path = Helper::remote_to_tmp_file( $customizer_file_url );
307 $widget_file_url = $data['widget_file_url'] ?? '';
308 $widget_file_path = Helper::remote_to_tmp_file( $widget_file_url );
309 $codestar_file_url = $data['codestar_file_url'] ?? '';
310 $codestar_file_path = Helper::remote_to_tmp_file( $codestar_file_url );
311 $with_images = isset( $data['with_images'] ) && true === $data['with_images'];
312
313 // Start the event stream.
314 header( 'Content-Type: text/event-stream, charset=UTF-8' );
315 header( 'Cache-Control: no-store' );
316 header( 'Connection: keep-alive' );
317
318 // Turn off PHP output compression.
319 // phpcs:disable WordPress.PHP.IniSet.Risky
320 ini_set( 'output_buffering', 'off' );
321 ini_set( 'zlib.output_compression', false );
322 // phpcs:enable WordPress.PHP.IniSet.Risky
323
324 if ( $GLOBALS['is_nginx'] ) {
325 // Setting this header instructs Nginx to disable fast-cgi buffering
326 // and disable gzip for this request.
327 header( 'X-Accel-Buffering: no' );
328 header( 'Content-Encoding: none' );
329 }
330
331 echo esc_html( ':' . str_repeat( ' ', 2048 ) . "\n\n" ); // 2KB padding for IE.
332
333 set_time_limit( 0 );
334
335 // Ensure we're not buffered.
336 wp_ob_end_flush_all();
337 flush();
338
339 do_action( 'ablocks/import/before_template_import_start', $data );
340 $template_import = Helper::import_template( $content_file_path, $with_images );
341 if ( ! is_wp_error( $template_import ) ) {
342 if ( ! empty( $customizer_file_path ) && ! is_wp_error( $customizer_file_path ) ) {
343 CustomizerImporter::import( $customizer_file_path );
344 }
345 if ( ! empty( $widget_file_path ) && ! is_wp_error( $widget_file_path ) ) {
346 WidgetImporter::import( $widget_file_path );
347 }
348 if ( ! empty( $codestar_file_path ) ) {
349 CodeStar::import( $codestar_file_path );
350 }
351 if ( isset( $data['redux_options'] ) && is_array( $data['redux_options'] ) && count( $data['redux_options'] ) > 0 ) {
352 Redux::import( $data['redux_options'] );
353 }
354 }
355 do_action( 'ablocks/import/template_import_finished', $data );
356
357 // Let the browser know we're done.
358 $complete = [
359 'action' => 'complete',
360 'error' => false,
361 ];
362 if ( is_wp_error( $template_import ) ) {
363 $complete['error'] = $template_import->get_error_message();
364 }
365 Helper::emit_sse_message( $complete );
366 exit;
367 }
368
369 /**
370 * Handle common list response.
371 *
372 * @param string $url URL.
373 * @param string $key Transient key.
374 *
375 * @return void
376 */
377 private function handle_list_response( string $url, string $key ): void {
378 $response = wp_safe_remote_get( $url );
379 if ( is_wp_error( $response ) ) {
380 wp_send_json_error( $response->get_error_message() );
381 }
382
383 $response_code = wp_remote_retrieve_response_code( $response );
384 $response = wp_remote_retrieve_body( $response );
385 $response = json_decode( $response, true );
386 if ( $response_code !== 200 ) {
387 wp_send_json_error( $response );
388 }
389
390 set_transient( $key, $response, WEEK_IN_SECONDS );
391 wp_send_json_success( $response );
392 }
393 }
394