PluginProbe ʕ •ᴥ•ʔ
Starter Sites & Templates by Neve / trunk
Starter Sites & Templates by Neve vtrunk
1.4.0 1.3.0 1.2.29 1.2.28 1.2.6 1.2.7 1.2.8 1.2.9 trunk 1.0.10 1.0.11 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.20 1.1.21 1.1.22 1.1.23 1.1.24 1.1.25 1.1.26 1.1.27 1.1.28 1.1.29 1.1.3 1.1.30 1.1.31 1.1.32 1.1.33 1.1.34 1.1.35 1.1.36 1.1.37 1.1.38 1.1.39 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.3 1.2.4 1.2.5
templates-patterns-collection / includes / TI_Beaver.php
templates-patterns-collection / includes Last commit date
Importers 2 months ago Admin.php 1 week ago Editor.php 1 year ago Elementor.php 1 year ago License.php 1 year ago Logger.php 2 years ago Main.php 1 week ago Rest_Server.php 2 weeks ago Sites_Listing.php 2 weeks ago Starter_Ranking.php 1 week ago TI_Beaver.php 1 year ago WP_Cli.php 3 months ago White_Label_Config.php 3 years ago
TI_Beaver.php
553 lines
1 <?php
2 /**
3 * Handles code for Beaver.
4 * It is not named Beaver.php on purpose as Beaver takes the module name from the class, hence naming it to Beaver.php would give
5 * the module the name of Beaver which can cause conflicts.
6 *
7 * @package templates-patterns-collection
8 */
9
10 namespace TIOB;
11
12
13 use TIOB\Main;
14 use FLBuilder;
15 use FLBuilderAJAX;
16 use FLBuilderModel;
17 use FLBuilderModule;
18 use FLBuilderSettingsCompat;
19 use FLBuilderAJAXLayout;
20 use FLBuilderUISettingsForms;
21
22 /**
23 * Class TI_Beaver
24 *
25 * @package templates-patterns-collection
26 */
27 class TI_Beaver extends FLBuilderModule {
28
29 /**
30 * The module construct, we need to pass some basic info here.
31 */
32 public function __construct() {
33 parent::__construct(
34 array(
35 'name' => __( 'Templates Cloud', 'templates-patterns-collection' ),
36 'description' => __( 'Templates Cloud by Neve.', 'templates-patterns-collection' ),
37 'category' => __( 'Templates Cloud', 'templates-patterns-collection' ),
38 'dir' => TIOB_PATH . 'beaver/',
39 'url' => TIOB_URL . 'beaver/',
40 'icon' => TIOB_URL . 'beaver/icon.svg',
41 )
42 );
43
44 $deps = require( TIOB_PATH . 'beaver/build/index.asset.php' );
45
46 $this->add_js( 'ti-tpc-beaver', $this->url . 'build/index.js', array_merge( $deps['dependencies'], array() ), $deps['version'], true );
47 $this->add_css( 'ti-tpc-beaver', $this->url . 'build/index.css', array( 'wp-components' ), $deps['version'] );
48 }
49
50 /**
51 * Get position of node.
52 */
53 static public function get_position( $node ) {
54 if ( empty( $node ) ) {
55 $row_position = FLBuilderModel::next_node_position( 'row' );
56
57 return $row_position;
58 }
59
60 $row = FLBuilderModel::get_node_parent_by_type( $node, 'row' );
61
62 return $row->position;
63 }
64
65 /**
66 * Import templates to Beaver.
67 */
68 static public function apply_template( $template, $position = 0 ) {
69 $response = self::get_template_content( $template );
70
71 $row_position = $position;
72 $new_items_count = 0;
73
74 if ( isset( $response->nodes ) ) {
75 // Get new ids for the template nodes.
76 $response->nodes = FLBuilderModel::generate_new_node_ids( $response->nodes );
77
78 // Filter the nodes for backwards compatibility with old settings.
79 $response->nodes = FLBuilderSettingsCompat::filter_layout_data( $response->nodes );
80
81 // Get the existing layout data and settings.
82 $layout_data = FLBuilderModel::get_layout_data();
83 $layout_settings = FLBuilderModel::get_layout_settings();
84
85 // Reposition rows?
86 foreach ( $response->nodes as $node_id => $node ) {
87 if ( 'row' === $node->type ) {
88 $response->nodes[ $node_id ]->position += $row_position;
89 $new_items_count ++;
90 }
91 }
92
93 if ( count( $response->nodes ) > 1 && count( $layout_data ) > 0 ) {
94 foreach ( $layout_data as $node_id => $node ) {
95 if ( 'row' === $node->type && (int) $position <= (int) $layout_data[ $node_id ]->position ) {
96 $layout_data[ $node_id ]->position += $new_items_count;
97 }
98 }
99 }
100
101 // Merge and update the layout data.
102 $data = array_merge( $layout_data, $response->nodes );
103
104 FLBuilderModel::update_layout_data( $data );
105
106 // Merge and update the layout settings.
107 if ( isset( $response->settings ) ) {
108 $settings = FLBuilderModel::merge_layout_settings( $layout_settings, $response->settings );
109 FLBuilderModel::update_layout_settings( $settings );
110 }
111 }
112
113 // Delete old asset cache.
114 FLBuilderModel::delete_asset_cache();
115
116 $response = self::get_template( $template, false );
117
118 if ( isset( $response['meta'] ) ) {
119 $post_id = FLBuilderModel::get_post_id();
120 $fields = json_decode( $response['meta'] );
121
122 foreach ( $fields as $key => $value ) {
123 update_post_meta( $post_id, $key, $value );
124 }
125 }
126
127 // Return the layout.
128 return array(
129 'layout_css' => isset( $settings ) ? $settings->css : null,
130 'layout' => FLBuilderAJAXLayout::render(),
131 'config' => FLBuilderUISettingsForms::get_node_js_config(),
132 );
133 }
134
135 /**
136 * Get template content by ID.
137 */
138 static public function get_template_content( $template_id ) {
139 $url = add_query_arg(
140 array(
141 'site_url' => get_site_url(),
142 'license_id' => apply_filters( 'tiob_license_key', 'free' ),
143 'cache' => uniqid(),
144 ),
145 TPC_TEMPLATES_CLOUD_ENDPOINT . 'templates/' . $template_id . '/import'
146 );
147
148 $response = wp_remote_get( esc_url_raw( $url ) );
149 $response = wp_remote_retrieve_body( $response );
150 $response = json_decode( $response, true );
151
152 if ( isset( $response['message'] ) ) {
153 return wp_send_json_error( $response['message'] );
154 }
155
156 $response = self::serialize_corrector( $response );
157 $response = unserialize( $response );
158
159 return $response;
160 }
161
162 /**
163 * Properly serialize JSON output.
164 */
165 static public function serialize_corrector( $serialized_string ) {
166 // at first, check if "fixing" is really needed at all. After that, security checkup.
167 if ( @unserialize( $serialized_string ) !== true && preg_match( '/^[aOs]:/', $serialized_string ) ) {
168 $serialized_string = preg_replace_callback(
169 '/s\:(\d+)\:\"(.*?)\";/s',
170 function ( $matches ) {
171 return 's:' . strlen( $matches[2] ) . ':"' . $matches[2] . '";';
172 },
173 $serialized_string
174 );
175 }
176
177 return $serialized_string;
178 }
179
180 /**
181 * Get template by ID.
182 */
183 static public function get_template( $template_id, $bool = true ) {
184 $url = add_query_arg(
185 array(
186 'site_url' => get_site_url(),
187 'license_id' => apply_filters( 'tiob_license_key', 'free' ),
188 'cache' => uniqid(),
189 ),
190 TPC_TEMPLATES_CLOUD_ENDPOINT . 'templates/' . esc_attr( $template_id )
191 );
192
193 $response = wp_remote_get( esc_url_raw( $url ) );
194 $response = wp_remote_retrieve_body( $response );
195 $response = json_decode( $response, true );
196
197 if ( ! $bool ) {
198 return $response;
199 }
200
201 if ( isset( $response['message'] ) ) {
202 return false;
203 }
204
205 return true;
206 }
207
208 /**
209 * Export row template.
210 */
211 static public function export_template( $node, $title ) {
212 $row = FLBuilderModel::get_node( $node );
213 $nodes = FLBuilderModel::get_nested_nodes( $node );
214 $post_id = FLBuilderModel::get_post_id();
215 $nodes[ $row->node ] = $row;
216 $obj = new \stdClass();
217 $obj->nodes = $nodes;
218 $body = serialize( $obj );
219
220 return self::save_template( $title, $body );
221 }
222
223 /**
224 * Save Beaver template to Templates Cloud.
225 */
226 static public function save_template( $title, $body, $is_page = false, $is_sync = false ) {
227 $post_id = FLBuilderModel::get_post_id();
228
229 $url = add_query_arg(
230 array(
231 'site_url' => get_site_url(),
232 'license_id' => apply_filters( 'tiob_license_key', 'free' ),
233 'template_name' => esc_attr( $title ),
234 'template_type' => 'beaver',
235 'link' => $is_page ? get_permalink( $post_id ) : '',
236 'cache' => uniqid(),
237 'meta' => $is_page ? json_encode( self::get_template_meta() ) : '',
238 ),
239 TPC_TEMPLATES_CLOUD_ENDPOINT . 'templates'
240 );
241
242 $response = wp_safe_remote_post(
243 $url,
244 array(
245 'body' => json_encode( $body ),
246 )
247 );
248
249 $response = wp_remote_retrieve_body( $response );
250 $response = json_decode( $response, true );
251
252 if ( isset( $response['message'] ) ) {
253 return wp_send_json_error( $response['message'] );
254 }
255
256 if ( $is_page ) {
257 update_post_meta( $post_id, '_ti_tpc_template_sync', $is_sync );
258
259 if ( isset( $response['template_id'] ) ) {
260 update_post_meta( $post_id, '_ti_tpc_template_id', $response['template_id'] );
261 }
262 }
263
264 return $response;
265 }
266
267 /**
268 * Template Meta.
269 */
270 static public function get_template_meta() {
271 $post_id = FLBuilderModel::get_post_id();
272 $fields = Main::get_meta_fields( $post_id, $type = 'beaver' );
273
274 if ( get_page_template_slug( $post_id ) ) {
275 $fields['_wp_page_template'] = get_page_template_slug( $post_id );
276 }
277
278 return $fields;
279 }
280
281 /**
282 * Publish Beaver template on Templates Cloud.
283 */
284 static public function publish_template( $slug, $screenshot, $premade ) {
285 $post_id = FLBuilderModel::get_post_id();
286 $template_id = get_post_meta( $post_id, '_ti_tpc_template_id', true );
287
288 $url = add_query_arg(
289 array(
290 'site_url' => get_site_url(),
291 'license_id' => apply_filters( 'tiob_license_key', 'free' ),
292 'template_site_slug' => $slug,
293 'template_thumbnail' => $screenshot,
294 'premade' => $premade,
295 'link' => get_permalink( $post_id ),
296 'cache' => uniqid(),
297 ),
298 TPC_TEMPLATES_CLOUD_ENDPOINT . 'templates/' . esc_attr( $template_id ) . '/publish'
299 );
300
301 $bearer = apply_filters( 'ti_tpc_editor_data', array() );
302
303 $response = wp_safe_remote_post(
304 $url,
305 array(
306 'headers' => array(
307 'Authorization' => 'Bearer ' . ( ! empty( $bearer['bearer'] ) && is_string( $bearer['bearer'] ) ? $bearer['bearer'] : '' ),
308 ),
309 )
310 );
311
312 $response = wp_remote_retrieve_body( $response );
313 $response = json_decode( $response, true );
314
315 if ( isset( $response['message'] ) ) {
316 return wp_send_json_error( $response['message'] );
317 }
318
319 update_post_meta( $post_id, '_ti_tpc_site_slug', $slug );
320 update_post_meta( $post_id, '_ti_tpc_screenshot_url', $screenshot );
321 update_post_meta( $post_id, '_ti_tpc_published', $premade );
322
323 return $response;
324 }
325
326 /**
327 * Initialize the Editor.
328 */
329 public function init() {
330 FLBuilderAJAX::add_action( 'ti_get_position', __CLASS__ . '::get_position', array( 'node' ) );
331 FLBuilderAJAX::add_action(
332 'ti_apply_template',
333 __CLASS__ . '::apply_template',
334 array(
335 'template',
336 'position',
337 )
338 );
339 FLBuilderAJAX::add_action( 'ti_export_template', __CLASS__ . '::export_template', array( 'node', 'title' ) );
340 FLBuilderAJAX::add_action( 'ti_export_page_template', __CLASS__ . '::export_page_template', array( 'is_sync' ) );
341 FLBuilderAJAX::add_action(
342 'ti_publish_template',
343 __CLASS__ . '::publish_template',
344 array(
345 'slug',
346 'screenshot',
347 'premade',
348 )
349 );
350
351 add_action( 'wp_head', array( $this, 'inline_script' ), 9 );
352 add_action( 'fl_builder_before_save_layout', array( $this, 'update_published_template' ), 10, 4 );
353
354 $is_pro = apply_filters( 'tiob_license_key', 'free' );
355
356 if ( $is_pro === 'free' ) {
357 return;
358 }
359
360 add_filter( 'fl_builder_main_menu', array( $this, 'add_export_menu' ), 10, 1 );
361 }
362
363 /**
364 * Add strings as global variable.
365 */
366 public function inline_script() {
367 $ti_tpc = apply_filters(
368 'ti_tpc_editor_data',
369 array(
370 'endpoint' => TPC_TEMPLATES_CLOUD_ENDPOINT,
371 'params' => array(
372 'site_url' => get_site_url(),
373 'license_id' => apply_filters( 'tiob_license_key', 'free' ),
374 'type' => 'beaver',
375 ),
376 'canPredefine' => apply_filters( 'ti_tpc_can_predefine', false ),
377 'pageTitle' => get_the_title(),
378 'postType' => get_post_type(),
379 'postTypes' => FLBuilderModel::get_post_types(),
380 'postMeta' => array(
381 '_ti_tpc_template_sync' => get_post_meta( get_the_ID(), '_ti_tpc_template_sync', true ),
382 '_ti_tpc_screenshot_url' => get_post_meta( get_the_ID(), '_ti_tpc_screenshot_url', true ),
383 '_ti_tpc_site_slug' => get_post_meta( get_the_ID(), '_ti_tpc_site_slug', true ),
384 '_ti_tpc_published' => get_post_meta( get_the_ID(), '_ti_tpc_published', true ),
385 ),
386 'exporter' => array(
387 'modalLabel' => __( 'Save Templates', 'templates-patterns-collection' ),
388 'textLabel' => __( 'Template Name', 'templates-patterns-collection' ),
389 'textPlaceholder' => __( 'Template', 'templates-patterns-collection' ),
390 'buttonLabel' => __( 'Save', 'templates-patterns-collection' ),
391 'toggleLabel' => __( 'Automatically sync to the cloud', 'templates-patterns-collection' ),
392 'cancelLabel' => __( 'Cancel', 'templates-patterns-collection' ),
393 'importFailed' => __( 'Import Failed', 'templates-patterns-collection' ),
394 'exportFailed' => __( 'Export Failed', 'templates-patterns-collection' ),
395 ),
396 'library' => array(
397 'templatesCloud' => 'Templates Cloud',
398 '404' => __( 'No templates available. Add a new one?', 'templates-patterns-collection' ),
399 'deleteItem' => __( 'Are you sure you want to delete this template?', 'templates-patterns-collection' ),
400 'synced' => __( 'This template is synced to a page.', 'templates-patterns-collection' ),
401 'tabs' => array(
402 'templates' => __( 'Page Templates', 'templates-patterns-collection' ),
403 'library' => __( 'My Library', 'templates-patterns-collection' ),
404 ),
405 'actions' => array(
406 'sync' => __( 'Sync Library', 'templates-patterns-collection' ),
407 'save' => sprintf(
408 // translators: %s: templates location.
409 __( 'Save to %s', 'templates-patterns-collection' ),
410 'templates-patterns-collection'
411 ),
412 'update' => __( 'Update', 'templates-patterns-collection' ),
413 'close' => __( 'Close', 'templates-patterns-collection' ),
414 'edit' => __( 'Edit', 'templates-patterns-collection' ),
415 'delete' => __( 'Delete', 'templates-patterns-collection' ),
416 'deleting' => __( 'Deleting', 'templates-patterns-collection' ),
417 'preview' => __( 'Preview', 'templates-patterns-collection' ),
418 'import' => __( 'Import', 'templates-patterns-collection' ),
419 ),
420 'filters' => array(
421 'sortLabel' => __( 'Sort by', 'templates-patterns-collection' ),
422 'sortLabels' => array(
423 'name' => __( 'Name', 'templates-patterns-collection' ),
424 'date' => __( 'Date', 'templates-patterns-collection' ),
425 'modified' => __( 'Last Modified', 'templates-patterns-collection' ),
426 'actions' => __( 'Actions', 'templates-patterns-collection' ),
427 'list' => __( 'List View', 'templates-patterns-collection' ),
428 'grid' => __( 'Grid View', 'templates-patterns-collection' ),
429 ),
430 'search' => __( 'Search', 'templates-patterns-collection' ),
431 'searchLabel' => __( 'Search Templates', 'templates-patterns-collection' ),
432 'clearSearch' => __( 'Clear search query', 'templates-patterns-collection' ),
433 ),
434 'export' => array(
435 'save' => __( 'Save', 'templates-patterns-collection' ),
436 'title' => sprintf(
437 // translators: %s: Templates Cloud
438 __( 'Save your page to %s', 'templates-patterns-collection' ),
439 'Templates Cloud'
440 ),
441 'labelScreenshot' => __( 'Screenshot URL', 'templates-patterns-collection' ),
442 'labelSlug' => __( 'Site Slug', 'templates-patterns-collection' ),
443 'publish' => __( 'Publish', 'templates-patterns-collection' ),
444 'unpublish' => __( 'Unpublish', 'templates-patterns-collection' ),
445 ),
446 ),
447 )
448 );
449 ?>
450 <script type="text/javascript">
451 window.tiTpc = <?php echo json_encode( $ti_tpc ); ?>;
452 </script>
453 <?php
454 }
455
456 /**
457 * Add export menu to Beaver Row's context.
458 */
459 public function add_export_menu( $views ) {
460 if ( in_array( get_post_type(), FLBuilderModel::get_post_types() ) ) {
461 $views['main']['items'][15] = array(
462 'label' => __( 'Save to Templates Cloud', 'templates-patterns-collection' ),
463 'type' => 'event',
464 'eventName' => 'tiTpcExport',
465 );
466 }
467
468 return $views;
469 }
470
471 /**
472 * Update published templates.
473 */
474 public function update_published_template( $post_id, $publish, $data, $settings ) {
475 if ( ! $publish ) {
476 return false;
477 }
478
479 $is_sync = get_post_meta( intval( $post_id ), '_ti_tpc_template_sync', true );
480
481 if ( $is_sync ) {
482 return self::export_page_template( true );
483 }
484 }
485
486 /**
487 * Export page template.
488 */
489 static public function export_page_template( $is_sync ) {
490 $title = get_the_title();
491 $title = empty( $title ) ? __( 'Template', 'templates-patterns-collection' ) : $title;
492 $nodes = FLBuilderModel::get_layout_data();
493 $settings = FLBuilderModel::get_layout_settings();
494 $obj = new \stdClass();
495 $obj->nodes = $nodes;
496 $obj->settings = $settings;
497 $body = serialize( $obj );
498 $post_id = FLBuilderModel::get_post_id();
499 $template_id = get_post_meta( $post_id, '_ti_tpc_template_id', true );
500
501 if ( ! empty( $template_id ) && self::get_template( $template_id ) ) {
502 return self::update_template( $template_id, $title, $body, $is_sync );
503 } else {
504 return self::save_template( $title, $body, true, $is_sync );
505 }
506 }
507
508 /**
509 * Update Beaver template to Templates Cloud.
510 */
511 static public function update_template( $template_id, $title, $body, $is_sync = false ) {
512 $post_id = FLBuilderModel::get_post_id();
513
514 $premade = get_post_meta( get_the_ID(), '_ti_tpc_published', true );
515
516 $url = add_query_arg(
517 array(
518 'site_url' => get_site_url(),
519 'license_id' => apply_filters( 'tiob_license_key', 'free' ),
520 'template_name' => esc_attr( $title ),
521 'template_type' => 'beaver',
522 'link' => get_permalink( $post_id ),
523 'cache' => uniqid(),
524 'meta' => json_encode( self::get_template_meta() ),
525 ),
526 TPC_TEMPLATES_CLOUD_ENDPOINT . 'templates/' . esc_attr( $template_id )
527 );
528
529 $response = wp_safe_remote_post(
530 $url,
531 array(
532 'body' => json_encode( $body ),
533 )
534 );
535
536 $response = wp_remote_retrieve_body( $response );
537 $response = json_decode( $response, true );
538
539 if ( isset( $response['message'] ) ) {
540 return wp_send_json_error( $response['message'] );
541 }
542
543 $post_id = FLBuilderModel::get_post_id();
544
545 update_post_meta( $post_id, '_ti_tpc_template_sync', $is_sync );
546 update_post_meta( $post_id, '_ti_tpc_template_id', $template_id );
547
548 return $response;
549 }
550 }
551
552 FLBuilder::register_module( 'TIOB\TI_Beaver', array() );
553