PluginProbe
bBlocks – Essential Gutenberg Blocks & Patterns Collection / trunk
bBlocks – Essential Gutenberg Blocks & Patterns Collection vtrunk
2.1.6 2.1.5 2.1.4 2.1.3 2.1.2 2.1.1 2.1.0 2.0.43 2.0.42 2.0.41 2.0.40 2.0.39 2.0.38 trunk 1.0 1.1 1.2 1.3 1.4 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 106 releases
b-blocks / includes / Templates / Templates.php

Templates.php in bBlocks – Essential Gutenberg Blocks & Patterns Collection trunk, at includes/Templates/Templates.php

194 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace BBlocks\Inc\Templates;
3
4 if ( !defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 require_once B_BLOCKS_DIR_PATH . '/includes/Templates/Image.php';
9
10 class Templates {
11 public function __construct() {
12 add_action( 'wp_ajax_bblocks_templates_main', [$this, 'bblocks_templates_main'] );
13 add_action( 'wp_ajax_bblocks_templates', [$this, 'bblocks_templates'] );
14 add_action( 'wp_ajax_bblocks_template_import', [$this, 'bblocks_template_import'] );
15 add_action( 'wp_ajax_bblocks_template_counts', [$this, 'bblocks_template_counts'] );
16 }
17
18 /**
19 * Accurate Free/Pro counts per category for a type.
20 *
21 * The taxonomy endpoint only exposes a category total plus a single global
22 * "pro" total, with no per-category free/pro split. So we pull the full
23 * lightweight catalog once (ID + category only, 100/page) and tally it.
24 * Result is cached in a transient since the catalog changes rarely.
25 *
26 * Shape: { all, free, pro, categories: { <cat>: { total, free, pro } } }
27 */
28 public function bblocks_template_counts(){
29 $nonce = sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ?? '' ) );
30
31 if( !wp_verify_nonce( $nonce, 'wp_ajax' )){
32 wp_send_json_error( 'Invalid Request' );
33 }
34
35 if ( ! current_user_can( 'edit_posts' ) ) {
36 wp_send_json_error( 'Unauthorized' );
37 }
38
39 $type = 'pages' === sanitize_text_field( wp_unslash( $_POST['type'] ?? 'patterns' ) ) ? 'pages' : 'patterns';
40
41 $cacheKey = 'bblocks_tpl_counts_' . $type;
42 $cached = get_transient( $cacheKey );
43 if ( false !== $cached ) {
44 wp_send_json_success( $cached );
45 }
46
47 $limit = 100;
48 $page = 0;
49 $items = [];
50 $batch = [];
51 $total = 0;
52 $guard = 0;
53
54 do {
55 $response = wp_remote_get( 'https://templates.bplugins.com/wp-json/gutenberg-templates/v1/blocks?' . http_build_query( [
56 'type' => $type,
57 'start' => $page,
58 'end' => $page + 1,
59 'category' => 'all',
60 'keywords' => '',
61 'limit' => $limit,
62 'fields' => 'ID,category',
63 ] ), [ 'timeout' => 20 ] );
64
65 if ( is_wp_error( $response ) ) {
66 break;
67 }
68
69 $body = json_decode( wp_remote_retrieve_body( $response ), true );
70 $batch = isset( $body['patterns'] ) && is_array( $body['patterns'] ) ? $body['patterns'] : [];
71 $total = isset( $body['count'] ) ? (int) $body['count'] : count( $items );
72 $items = array_merge( $items, $batch );
73
74 $page++;
75 $guard++;
76 } while ( count( $batch ) === $limit && count( $items ) < $total && $guard < 20 );
77
78 $cats = [];
79 $allFree = 0;
80 $allPro = 0;
81
82 foreach ( $items as $it ) {
83 $itemCats = isset( $it['category'] ) && is_array( $it['category'] ) ? $it['category'] : [];
84 $isPro = in_array( 'pro', $itemCats, true );
85
86 if ( $isPro ) { $allPro++; } else { $allFree++; }
87
88 foreach ( $itemCats as $c ) {
89 if ( 'pro' === $c || 'free' === $c ) {
90 continue;
91 }
92 if ( ! isset( $cats[ $c ] ) ) {
93 $cats[ $c ] = [ 'total' => 0, 'free' => 0, 'pro' => 0 ];
94 }
95 $cats[ $c ]['total']++;
96 if ( $isPro ) { $cats[ $c ]['pro']++; } else { $cats[ $c ]['free']++; }
97 }
98 }
99
100 $data = [
101 'all' => count( $items ),
102 'free' => $allFree,
103 'pro' => $allPro,
104 'categories' => (object) $cats,
105 ];
106
107 // Cache only a complete tally (don't cache partial results from a failed run).
108 if ( count( $items ) >= $total && $total > 0 ) {
109 set_transient( $cacheKey, $data, 6 * HOUR_IN_SECONDS );
110 }
111
112 wp_send_json_success( $data );
113 }
114
115 public function bblocks_templates_main(){
116 $nonce = sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ?? null ) );
117 $type = sanitize_text_field( wp_unslash( $_POST['type'] ?? 'patterns' ) );
118
119 if( !wp_verify_nonce( $nonce, 'wp_ajax' )){
120 wp_send_json_error( 'Invalid Request' );
121 }
122
123 if ( ! current_user_can( 'edit_posts' ) ) {
124 wp_send_json_error( 'Unauthorized' );
125 }
126
127 $typeFilter = 'patterns' === $type ? 'patterns-category': 'pages-category';
128 // $response = wp_remote_get('https://templates.bplugins.com/wp-json/gutenberg-templates/v1/taxonomy/taxonomies/plugin,type,'.$typeFilter.'-category');
129 $response = wp_remote_get("https://templates.bplugins.com/wp-json/gutenberg-templates/v1/taxonomy/taxonomies/plugin,type,{$typeFilter}");
130
131 $body = json_decode( wp_remote_retrieve_body( $response ) );
132 wp_send_json_success( $body );
133 }
134
135 public function bblocks_templates(){
136 $nonce = sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ?? null ) );
137
138 if( !wp_verify_nonce( $nonce, 'wp_ajax' )){
139 wp_send_json_error( 'Invalid Request' );
140 }
141
142 if ( ! current_user_can( 'edit_posts' ) ) {
143 wp_send_json_error( 'Unauthorized' );
144 }
145
146 $type = sanitize_text_field( wp_unslash( $_POST['type'] ?? 'patterns') ) ;
147 $category = sanitize_text_field( wp_unslash( $_POST['category'] ?? 'all' ) );
148 $pageNumber = absint( wp_unslash( $_POST['pageNumber'] ?? 1 ) );
149 $pageNumber = $pageNumber > 0 ? $pageNumber : 1;
150 $start = $pageNumber - 1;
151 $search = sanitize_text_field( wp_unslash( $_POST['search'] ?? '' ) );
152
153 $typeFilter = 'patterns' === $type ? 'patterns': 'pages';
154
155 try {
156 $response = wp_remote_get( 'https://templates.bplugins.com/wp-json/gutenberg-templates/v1/blocks?' . http_build_query( [
157 'type' => $typeFilter,
158 'start' => $start,
159 'end' => $pageNumber,
160 'category' => $category,
161 'keywords' => $search,
162 'fields' => 'ID,category,keywords,original_content,thumbnail,title,type,url',
163 ] ) );
164
165 // old
166 // $response = wp_remote_get( "https://templates.bplugins.com/wp-json/gutenberg-templates/v1/$typeFilter?start=$start&end=$pageNumber&category=$category&keywords=$search&fields=ID,category,keywords,original_content,thumbnail,title,type,url" );
167
168 $body = json_decode( wp_remote_retrieve_body( $response ) );
169 wp_send_json_success( $body );
170 } catch (\Throwable $th) {
171 wp_send_json_error( $th->getMessage() );
172 }
173 }
174
175 public function bblocks_template_import(){
176 $nonce = sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ?? '' ) );
177
178 if( !wp_verify_nonce( $nonce, 'wp_ajax' )){
179 wp_send_json_error( 'Invalid Request' );
180 }
181
182 if ( ! current_user_can( 'edit_posts' ) ) {
183 wp_send_json_error( 'Unauthorized' );
184 }
185
186 try {
187 $data = Image::instance()->maybe_import_images( wp_unslash( $_POST['original_content'] ?? '' ) );
188 wp_send_json_success( $data );
189 } catch ( \Throwable $th ) {
190 wp_send_json_error( $th->getMessage() );
191 }
192 }
193 }
194 new Templates();