PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.5.0
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.5.0
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 / Items.php

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

611 lines 16.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Templately\API;
4
5 use WP_REST_Request;
6 use Templately\Utils\Database;
7
8 use function json_decode;
9
10 class Items extends API {
11 public function permission_check( WP_REST_Request $request ) {
12 $this->request = $request;
13
14 $_route = $request->get_route();
15 if( $_route === '/templately/v1/items/favourite' || $_route === '/templately/v1/items/rating' ) {
16 return parent::permission_check( $request );
17 }
18
19 return true;
20 }
21
22 public function register_routes() {
23 $this->get( 'items', [ $this, 'get_items' ], [
24 'type' => [
25 'default' => 'items',
26 'required' => false,
27 // 'validate_callback' => function( $param, $request, $key ){
28 // return in_array( $param, [ 'items', 'sections', 'blocks', 'packs', 'pages' ], true );
29 // }
30 ],
31 'platform' => [
32 'default' => 'elementor',
33 'required' => false
34 ],
35 'per_page' => [
36 'default' => 40,
37 'required' => false
38 ],
39 ] );
40
41 // only number
42 $this->get( 'items/(?P<id>[0-9]+)', [ $this, 'get_item_by_id' ], [
43 'id' => [
44 'required' => true,
45 ],
46 'type' => [
47 'default' => 'block'
48 ]
49 ] );
50
51 // with slug
52 $this->get( 'items/(?P<slug>[a-zA-Z0-9-]+)', [ $this, 'get_item' ], [
53 'slug' => [
54 'required' => true,
55 ],
56 'type' => [
57 'default' => 'block'
58 ]
59 ] );
60
61 $this->get( 'items/search/(?P<keyword>[a-zA-Z0-9-]+)', [ $this, 'get_search_results' ], [
62 'keyword' => [
63 'required' => true,
64 ],
65 'platform' => [
66 'default' => 'elementor',
67 ],
68 'query_type' => [
69 'default' => 'block',
70 ],
71 ] );
72
73 $this->post( 'items/favourite', [ $this, 'set_favourite' ] );
74 $this->post( 'items/rating', [ $this, 'set_rating' ] );
75 $this->get( 'items-count', [ $this, 'get_counts' ] );
76 $this->get( 'featured-items', [ $this, 'featured_items' ] );
77 $this->get( 'trending-items', [ $this, 'trending_items' ] );
78 $this->get( 'related-items', [ $this, 'related_items' ]);
79 }
80
81 /**
82 * @param string $type
83 *
84 * @return string
85 */
86 public function get_query_types( $type = 'blocks' ) {
87 $item_types = ( $type === 'blocks' || $type === 'sections' ) ? 'items' : trim( $type );
88 return in_array( $item_types, [ 'items', 'pages', 'packs' ], true ) ? $item_types : false;
89 }
90
91 public function get_items( WP_REST_Request $request ) {
92 $_type = $this->get_param( 'type', 'blocks' );
93 $type = $this->get_query_types( $_type );
94 $plan = $this->get_param( 'plan', 'all' );
95 $plan_type = $this->get_plan( $plan );
96 $platform = $this->get_param( 'platform', 'elementor' );
97 $search = $this->get_param( 'search' );
98 $include_search = $this->get_param( 'include_search' );
99 $page = $this->get_param( 'page', 1, 'intval' );
100 $per_page = $this->get_param( 'per_page', 40, 'intval' );
101 $template_type_id = $this->get_param( 'template_type_id', 0, 'intval' );
102 $category_id = $this->get_param( 'category_id', 0, 'intval' );
103
104 $dependencies = $request->get_param( 'dependencies' );
105 $tags = $request->get_param( 'tags' );
106
107 $funcArgs = [
108 'page' => $page,
109 'per_page' => $per_page,
110 'platform' => $platform,
111 ];
112
113 if ( $plan_type > 1 ) {
114 $funcArgs['plan_type'] = $plan_type;
115 }
116
117 if ( $category_id ) {
118 $funcArgs['category_id'] = $category_id;
119 }
120 if ( $template_type_id > 0 ) {
121 $funcArgs['template_type_id'] = $template_type_id;
122 }
123 if ( ! empty( $dependencies['include'] ) || ! empty( $dependencies['exclude'] ) ) {
124 $funcArgs['dependencies'] = wp_slash( json_encode( $dependencies ) );
125 }
126 if ( ! empty( $tags ) ) {
127 $funcArgs['tag_id'] = wp_slash( json_encode( $tags ) );
128 }
129
130 if ( ! empty( $search ) ) {
131 $funcArgs['search'] = $search;
132 }
133
134 if ( ! empty( $include_search ) ) {
135 $funcArgs['include_search'] = $include_search;
136 }
137
138 $query = 'total_page, current_page, data { id, fullsite_import, name, price, rating, downloads, type, template_type{ slug }, slug, favourite_count, thumbnail, thumbnail2, thumbnail3 }';
139 if( $type !== 'packs' ) {
140 $query = 'total_page, current_page, data { id, name, price, rating, downloads, type, template_type{ slug }, slug, favourite_count, dependencies{ id, name, icon, plugin_file, plugin_original_slug, is_pro, link }, thumbnail }';
141 }
142
143 if( $type === false ) {
144 return $this->error( 'invalid_type_call', __( 'Invalid Type Call', 'templately' ) );
145 }
146
147 return $this->http()->query(
148 $type,
149 $query,
150 $funcArgs
151 )->post();
152 }
153
154 public function get_item() {
155 $slug = $this->get_param( 'slug' );
156 $_type = $this->get_param( 'type', 'blocks' );
157 $type = $this->get_query_types( $_type );
158
159 if ( empty( $slug ) ) {
160 return $this->error(
161 'invalid_item_slug',
162 __( 'Items slug cannot be empty.', 'templately' ),
163 'items/:slug',
164 '400'
165 );
166 }
167
168 if( $type === false ) {
169 return $this->error( 'invalid_type_call', __( 'Invalid Type Call', 'templately' ) );
170 }
171
172 $items_params = 'id, name, rating, type, description, slug, price, features, favourite_count, is_favourite, is_reviewed, thumbnail, downloads, categories{ id, name, slug }, dependencies{ id, name, icon, plugin_file, plugin_original_slug, is_pro, link }, tags{ name, id }, categories{ name, id }, screenshots{ url }, banner, published_at, updated_at, is_trending, badges, pack{ id, name, slug, items{ id, price, name, type, slug, thumbnail } }, live_url, template_type{ id, name, slug }';
173 $params = 'data { ' . $items_params . ', variations { name, slug, type, platform } }';
174
175 if ( $type == 'packs' ) {
176 $params = 'data { id, fullsite_import, ai_compatible, has_settings, has_attachments, name, rating, type, slug, live_url, price, features, favourite_count, is_favourite, is_reviewed, thumbnail, description, tags{ name, id }, banner, published_at, updated_at, is_trending, badges, template_type{ id, name, slug } downloads, categories{ id, name, slug }, items { ' . $items_params . ' }, variations { name, slug, type, platform } }';
177 }
178
179 $args = [
180 'slug' => $slug,
181 ];
182 if (!empty($this->api_key)) {
183 $args['api_key'] = $this->api_key;
184 }
185
186 $response = $this->http()->query( $type, $params, $args )->post();
187
188 if ( is_wp_error( $response ) ) {
189 return $response;
190 }
191
192 if( empty( $response['data'] ) ) {
193 return $this->error(
194 'invalid_response',
195 __('Item data not found', 'templately'),
196 '/items\/' . $slug,
197 '404'
198 );
199 }
200
201 return current( $response['data'] );
202 }
203
204 public function get_item_by_id() {
205 $id = (int) $this->get_param( 'id' );
206 $_type = $this->get_param( 'type', 'blocks' );
207 $type = $this->get_query_types( $_type );
208
209 if ( empty( $id ) ) {
210 return $this->error(
211 'invalid_item_slug',
212 __( 'Items id cannot be empty.', 'templately' ),
213 'items/:id',
214 '400'
215 );
216 }
217
218 if( $type === false ) {
219 return $this->error( 'invalid_type_call', __( 'Invalid Type Call', 'templately' ) );
220 }
221
222 $items_params = 'id, name, rating, type, description, slug, price, features, favourite_count, is_favourite, is_reviewed, thumbnail, downloads, categories{ id, name, slug }, dependencies{ id, name, icon, plugin_file, plugin_original_slug, is_pro, link }, tags{ name, id }, categories{ name, id }, screenshots{ url }, banner, published_at, updated_at, is_trending, badges, pack{ id, name, slug, items{ id, price, name, type, slug, thumbnail } }, live_url, template_type{ id, name, slug }';
223 $params = 'data { ' . $items_params . ', variations { name, slug, type, platform } }';
224
225 if ( $type == 'packs' ) {
226 $params = 'data { id, fullsite_import, ai_compatible, has_settings, has_attachments, name, rating, type, slug, live_url, price, features, favourite_count, is_favourite, is_reviewed, thumbnail, description, tags{ name, id }, banner, published_at, updated_at, is_trending, badges, template_type{ id, name, slug } downloads, categories{ id, name, slug }, items { ' . $items_params . ' }, variations { name, slug, type, platform } }';
227 }
228
229 $args = [
230 'id' => $id,
231 ];
232 if (!empty($this->api_key)) {
233 $args['api_key'] = $this->api_key;
234 }
235
236 $response = $this->http()->query( $type, $params, $args )->post();
237
238 if ( is_wp_error( $response ) ) {
239 return $response;
240 }
241
242 if( empty( $response['data'] ) ) {
243 return $this->error(
244 'invalid_response',
245 __('Item data not found', 'templately'),
246 '/items\/' . $id,
247 '404'
248 );
249 }
250
251 return current( $response['data'] );
252 }
253
254 public function get_search_results( WP_REST_Request $request ) {
255 $keyword = $request->get_param( 'keyword' );
256 $platform = $request->get_param( 'platform' );
257 $query_type = $request->get_param( 'query_type' );
258
259 if ( empty( $keyword ) ) {
260 return $this->error(
261 'invalid_search_keyword',
262 __( 'Search keyword cannot be empty.', 'templately' ),
263 'items/search/:keyword',
264 '400'
265 );
266 }
267
268 $funcArgs = [
269 'search' => $keyword,
270 'platform' => $platform,
271 'query_type' => $query_type
272 ];
273
274 $response = $this->http()->query(
275 'getItemsAndPacks',
276 'total_page, current_page, data { id, name, rating, type, slug, favourite_count, thumbnail }',
277 $funcArgs
278 )->post();
279
280 if( is_wp_error( $response ) ){
281 return $response;
282 }
283
284 $modified_response = [
285 'data' => []
286 ];
287
288 if ( ! empty( $response['data'] ) ) {
289 $modified_response['data'] = array_map( function( $item ){
290 $item['id'] = (int) $item['id'];
291 return $item;
292 }, $response['data'] );
293 unset( $response['data'] );
294 }
295
296 return array_merge( $response, $modified_response );
297 }
298
299 public function set_favourite(){
300 $id = $this->get_param( 'id', 0, 'intval' );
301 $type = $this->get_param( 'itemType', 'block' );
302 $action = $this->get_param( 'action', 'do' );
303
304 $query = 'status, message, data';
305 if( $action === 'undo' ) {
306 $query = '';
307 }
308
309 $funcArgs = [
310 'api_key' => $this->api_key,
311 'type_id' => $id,
312 'type' => $type,
313 ];
314
315 $response = $this->http()->mutation(
316 $action === 'undo' ? 'unFavourite' : 'favourite',
317 $query,
318 $funcArgs
319 )->post();
320
321 if( is_wp_error( $response ) ) {
322 return $response;
323 }
324
325 $_response = [];
326
327 $_data = $response;
328 if( $action == 'do' ) {
329 if( ! empty( $_data['data'] ) && $_data['status'] === 'success' ) {
330 $_data['data'] = $_temp_data = json_decode( $_data['data'] );
331 $_temp_data = [ $_temp_data ];
332
333 $_favourites = $this->utils('options')->get('favourites');
334 $_favourites = $this->utils('helper')->normalizeFavourites( $_temp_data, $_favourites );
335 $this->utils('options')->set('favourites', $_favourites);
336
337 $_response['status'] = 'success';
338 $_response['data'] = $_favourites;
339 }
340 }
341
342 if( $action == 'undo' ) {
343 $_temp_data = [
344 'id' => $id,
345 'type' => $type == 'block' || $type == 'page' ? 'item' : 'pack'
346 ];
347
348 if( $response == 1 || $response === false ) {
349 $_favourites = $this->utils('options')->get('favourites');
350 $_favourites = $this->utils('helper')->normalizeFavourites( $_temp_data, $_favourites, true );
351 $this->utils('options')->set('favourites', $_favourites);
352
353 $_response['status'] = 'success';
354 $_response['data'] = $_favourites;
355 } else {
356 $_response['status'] = 'error';
357 $_response['message'] = __( 'Unfavourite Action Failed: Something went wrong.', 'templately' );
358 }
359 }
360
361 return $_response;
362 }
363
364 public function set_rating(){
365 $type_id = $this->get_param( 'type_id', 0, 'intval' );
366 $itemType = $this->get_param( 'itemType', 'pack' );
367 $rating = $this->get_param( 'rating', 5, 'intval' );
368
369 $query = 'status, message, data';
370
371 $funcArgs = [
372 'api_key' => $this->api_key,
373 'type_id' => $type_id,
374 'type' => $itemType,
375 'rating' => $rating,
376 ];
377
378 $response = $this->http()->mutation(
379 'review',
380 $query,
381 $funcArgs
382 )->post();
383
384 if( is_wp_error( $response ) ) {
385 return $response;
386 }
387
388 if( empty( $response['data'] ) ) {
389 return $this->error(
390 'invalid_response',
391 __('Something went wrong.', 'templately'),
392 '/items\/rating',
393 '404'
394 );
395 }
396
397 if( ! empty( $response['data'] ) && $response['status'] === 'success' ) {
398 $response['data'] = json_decode( $response['data'], true );
399
400 $_ratings = $this->utils('options')->get('reviews', []);
401 // $_reviews = $this->utils( 'helper' )->normalizeReviews( $response['user']['reviews'] );
402 $_ratings[ $itemType ][ $type_id ] = $rating;
403 $this->utils('options')->set('reviews', $_ratings);
404
405 $_ratings[ $itemType ][ "avg_$type_id" ] = (float) $response['data']['avg_rating'];
406 $response['data']['reviews'] = $_ratings;
407 }
408
409 return $response;
410 }
411
412 public function get_counts(){
413 $defaults = Database::get_transient( 'counts' );
414 if( $defaults ) {
415 return $defaults;
416 }
417
418 $defaults = [
419 'elementor' => [
420 'items' => [
421 'total' => '1469',
422 'starter' => '964',
423 'pro' => '415',
424 ],
425 'blocks' => [
426 'total' => '517',
427 'starter' => '358',
428 'pro' => '159',
429 ],
430 'pages' => [
431 'total' => '803',
432 'starter' => '506',
433 'pro' => '297',
434 ],
435 'packs' => [
436 'total' => '149',
437 'starter' => '100',
438 'pro' => '49',
439 ]
440 ],
441 'gutenberg' => [
442 'blocks' => [
443 'total' => '3',
444 'starter' => '3',
445 'pro' => '0',
446 ],
447 'pages' => [
448 'total' => '3',
449 'starter' => '3',
450 'pro' => '0',
451 ],
452 'packs' => [
453 'total' => '3',
454 'starter' => '3',
455 'pro' => '0',
456 ],
457 ]
458 ];
459
460 $response = $this->http()->query(
461 'getCounts',
462 'key, value'
463 )->post();
464
465 if ( is_wp_error( $response ) ) {
466 return $defaults;
467 }
468
469 $new_array = [
470 'items' => [],
471 'blocks' => [],
472 'pages' => [],
473 'packs' => [],
474 ];
475 $_new_data = [];
476
477 array_walk( $response, function( $item ) use ( &$new_array, &$_new_data ) {
478 if( in_array( $item['key'] , ['elementor', 'gutenberg'], true ) ) {
479 $values = json_decode($item['value'], true);
480
481 array_walk( $values, function( $_item ) use ( &$new_array ) {
482 $new_key = explode('-', $_item['key']);
483 if( count( $new_key ) === 2 ) {
484 if( isset( $new_array[ $new_key[1] ] )) {
485 $new_array[ $new_key[1] ] = array_merge( $new_array[ $new_key[1] ], [ $new_key[0] => $_item['value'] ] );
486 $temp_array = $new_array[ $new_key[1] ];
487 unset( $temp_array['total'] );
488 $new_array[ $new_key[1] ]['total'] = array_sum( $temp_array );
489 }
490 }
491 });
492
493 $_new_data[ $item['key'] ] = $new_array;
494 }
495 });
496
497
498 Database::set_transient( 'counts', $_new_data );
499
500 return $_new_data;
501 }
502
503 /**
504 * Get Featured Item List
505 * @param WP_REST_Request $request
506 * @return mixed
507 */
508 public function featured_items(WP_REST_Request $request){
509 $platform = $request->get_param( 'platform' );
510 $defaults = Database::get_transient( "featuredItems_{$platform}" );
511 if( $defaults ) {
512 return $defaults;
513 }
514
515 $funcArgs = [
516 // 'page' => 1,
517 // 'per_page' => 10,
518 'platform' => $platform,
519 ];
520 $response = $this->http()->query(
521 'featuredItems',
522 'data{ id, name, slug, price, type, thumbnail, badges }',
523 $funcArgs
524 )->post();
525
526 if( ! is_wp_error( $response ) ) {
527 Database::set_transient( 'featuredItems', $response );
528 }
529
530 return $response;
531 }
532
533 /**
534 * Get Trending Item List
535 * @param WP_REST_Request $request
536 * @return mixed
537 */
538 public function trending_items(WP_REST_Request $request){
539 $platform = $request->get_param( 'platform' );
540 $defaults = Database::get_transient( "trendingItems_{$platform}" );
541 if( $defaults ) {
542 return $defaults;
543 }
544
545 $funcArgs = [
546 // 'page' => 1,
547 // 'per_page' => 10,
548 'platform' => $platform,
549 ];
550 $response = $this->http()->query(
551 'trendingItems',
552 'data{ id, name, slug, price, type, thumbnail, badges }',
553 $funcArgs
554 )->post();
555
556 if( ! is_wp_error( $response ) ) {
557 Database::set_transient( 'trendingItems', $response );
558 }
559
560 return $response;
561 }
562
563 /**
564 * Get Related Item List
565 * @param WP_REST_Request $request
566 * @return mixed
567 */
568 public function related_items(WP_REST_Request $request){
569 $item_id = (int) $request->get_param( 'item_id' );
570 $type = $request->get_param( '_type' );
571
572 if ( empty( $item_id ) ) {
573 return $this->error(
574 'invalid_item_id',
575 __( 'Item ID cannot be empty.', 'templately' ),
576 'related-items',
577 '400'
578 );
579 }
580
581 if ( empty( $type ) ) {
582 return $this->error(
583 'invalid_type',
584 __( 'Type cannot be empty.', 'templately' ),
585 'related-items',
586 '400'
587 );
588 }
589
590 $funcArgs = [
591 'id' => $item_id,
592 'type' => $type,
593 'limit' => 4, // Limit to 3 related items
594 ];
595
596 $response = $this->http()->query(
597 'relatedItems',
598 'id, name, slug, price, type, thumbnail, badges',
599 $funcArgs
600 )->post();
601
602 if( is_wp_error( $response ) ) {
603 return $response;
604 }
605
606 return [
607 'status' => 'success',
608 'data' => $response,
609 ];
610 }
611 }