PluginProbe ʕ •ᴥ•ʔ
Page Builder by SiteOrigin / 2.16.16
Page Builder by SiteOrigin v2.16.16
2.34.3 2.34.2 2.29.5 2.29.6 2.29.7 2.29.8 2.29.9 2.3 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.31.4 2.31.5 2.31.6 2.31.7 2.31.8 2.32.0 2.32.1 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.34.0 2.34.1 2.4 2.4.1 2.4.10 2.4.11 2.4.12 2.4.13 2.4.14 2.4.15 2.4.16 2.4.17 2.4.18 2.4.19 2.4.2 2.4.20 2.4.21 2.4.22 2.4.23 2.4.24 2.4.25 2.4.3 2.4.4 2.4.5 2.4.6 2.4.8 2.4.9 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.14 2.5.15 2.5.16 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.6.5 2.6.6 2.6.7 2.6.8 2.6.9 2.7.0 2.7.1 2.7.2 2.7.3 2.8.0 2.8.1 2.8.2 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 trunk 2.10.0 2.10.1 2.10.10 2.10.11 2.10.12 2.10.13 2.10.14 2.10.15 2.10.16 2.10.17 2.10.2 2.10.3 2.10.4 2.10.5 2.10.6 2.10.7 2.10.8 2.10.9 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.12.0 2.12.1 2.12.2 2.12.3 2.12.4 2.12.5 2.12.6 2.13.0 2.13.1 2.13.2 2.14.0 2.14.1 2.14.2 2.14.3 2.15.0 2.15.1 2.15.2 2.15.3 2.16.0 2.16.1 2.16.10 2.16.11 2.16.12 2.16.13 2.16.14 2.16.15 2.16.16 2.16.17 2.16.18 2.16.19 2.16.2 2.16.3 2.16.4 2.16.5 2.16.6 2.16.7 2.16.8 2.16.9 2.17.0 2.18.0 2.18.1 2.18.2 2.18.3 2.18.4 2.19.0 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.21.1 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.26.1 2.26.2 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.10 2.29.11 2.29.12 2.29.13 2.29.14 2.29.15 2.29.16 2.29.17 2.29.18 2.29.19 2.29.2 2.29.20 2.29.21 2.29.22 2.29.3 2.29.4
siteorigin-panels / siteorigin-panels.php
siteorigin-panels Last commit date
compat 3 years ago css 3 years ago inc 3 years ago js 3 years ago lang 4 years ago settings 4 years ago tpl 4 years ago widgets 4 years ago license.txt 11 years ago readme.txt 3 years ago siteorigin-panels.php 3 years ago wpml-config.xml 4 years ago
siteorigin-panels.php
775 lines
1 <?php
2 /*
3 Plugin Name: Page Builder by SiteOrigin
4 Plugin URI: https://siteorigin.com/page-builder/
5 Description: A drag and drop, responsive page builder that simplifies building your website.
6 Version: 2.16.16
7 Author: SiteOrigin
8 Author URI: https://siteorigin.com
9 License: GPL3
10 License URI: http://www.gnu.org/licenses/gpl.html
11 Donate link: http://siteorigin.com/page-builder/#donate
12 */
13
14 define( 'SITEORIGIN_PANELS_VERSION', '2.16.16' );
15 if ( ! defined( 'SITEORIGIN_PANELS_JS_SUFFIX' ) ) {
16 define( 'SITEORIGIN_PANELS_JS_SUFFIX', '.min' );
17 }
18 define( 'SITEORIGIN_PANELS_CSS_SUFFIX', '.min' );
19
20 require_once plugin_dir_path( __FILE__ ) . 'inc/functions.php';
21
22 class SiteOrigin_Panels {
23
24 function __construct() {
25 register_activation_hook( __FILE__, array( 'SiteOrigin_Panels', 'activate' ) );
26
27 // Register the autoloader.
28 spl_autoload_register( array( $this, 'autoloader' ) );
29
30 add_action( 'plugins_loaded', array( $this, 'version_check' ) );
31 add_action( 'plugins_loaded', array( $this, 'init' ) );
32 add_action( 'plugins_loaded', array( $this, 'init_compat' ), 100 );
33 add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ), 100 );
34
35 add_action( 'widgets_init', array( $this, 'widgets_init' ) );
36
37 add_filter( 'body_class', array( $this, 'body_class' ) );
38 add_filter( 'siteorigin_panels_data', array( $this, 'process_panels_data' ), 5 );
39 add_filter( 'siteorigin_panels_widget_class', array( $this, 'fix_namespace_escaping' ), 5 );
40
41 add_action( 'activated_plugin', array($this, 'activation_flag_redirect') );
42 add_action( 'admin_init', array($this, 'activation_do_redirect') );
43
44 if (
45 is_admin() ||
46 ( wp_doing_ajax() && isset($_REQUEST['action']) && $_REQUEST['action'] == 'inline-save' )
47 ) {
48 SiteOrigin_Panels_Admin::single();
49 }
50
51 if ( is_admin() ) {
52 // Setup all the admin classes.
53 SiteOrigin_Panels_Settings::single();
54 SiteOrigin_Panels_Revisions::single();
55 }
56
57 // Include the live editor file if we're in live editor mode.
58 if ( self::is_live_editor() ) {
59 SiteOrigin_Panels_Live_Editor::single();
60 }
61
62 SiteOrigin_Panels::renderer();
63 SiteOrigin_Panels_Styles_Admin::single();
64
65 if ( siteorigin_panels_setting( 'bundled-widgets' ) && ! function_exists( 'origin_widgets_init' ) ) {
66 require_once plugin_dir_path( __FILE__ ) . 'widgets/widgets.php';
67 }
68
69 SiteOrigin_Panels_Widget_Shortcode::init();
70
71 // We need to generate fresh post content.
72 add_filter( 'the_content', array( $this, 'generate_post_content' ) );
73 add_filter( 'woocommerce_format_content', array( $this, 'generate_woocommerce_content' ) );
74 add_filter( 'wp_enqueue_scripts', array( $this, 'generate_post_css' ) );
75
76 // Remove the default excerpt function.
77 add_filter( 'get_the_excerpt', array( $this, 'generate_post_excerpt' ), 9 );
78
79 // Content cache has been removed. SiteOrigin_Panels_Cache_Renderer just deletes any existing caches.
80 SiteOrigin_Panels_Cache_Renderer::single();
81
82 if ( function_exists( 'register_block_type' ) ) {
83 SiteOrigin_Panels_Compat_Layout_Block::single();
84 }
85
86 define( 'SITEORIGIN_PANELS_BASE_FILE', __FILE__ );
87 }
88
89
90 public static function single() {
91 static $single;
92 return empty( $single ) ? $single = new self() : $single;
93 }
94
95 /**
96 * Get an instance of the renderer
97 *
98 * @return SiteOrigin_Panels_Renderer
99 */
100 public static function renderer() {
101 static $renderer;
102 if ( empty( $renderer ) ) {
103 switch( siteorigin_panels_setting( 'legacy-layout' ) ) {
104 case 'always':
105 $renderer = SiteOrigin_Panels_Renderer_Legacy::single();
106 break;
107
108 case 'never':
109 $renderer = SiteOrigin_Panels_Renderer::single();
110 break;
111
112 default:
113 $renderer = self::is_legacy_browser() ?
114 SiteOrigin_Panels_Renderer_Legacy::single() :
115 SiteOrigin_Panels_Renderer::single();
116 break;
117 }
118 }
119
120 return $renderer;
121 }
122
123 public static function is_legacy_browser() {
124 $agent = ! empty( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '';
125 if ( empty( $agent ) ) return false;
126
127 return
128 // IE lte 11
129 ( preg_match('/Trident\/(?P<v>\d+)/i', $agent, $B) && $B['v'] <= 7 ) ||
130 // Chrome lte 25
131 ( preg_match('/Chrome\/(?P<v>\d+)/i', $agent, $B) && $B['v'] <= 25 ) ||
132 // Firefox lte 21
133 ( preg_match('/Firefox\/(?P<v>\d+)/i', $agent, $B) && $B['v'] <= 21 ) ||
134 // Safari lte 7
135 ( preg_match('/Version\/(?P<v>\d+).*?Safari\/\d+/i', $agent, $B) && $B['v'] <= 6 );
136 }
137
138 /**
139 * Autoload Page Builder specific classses.
140 *
141 * @param $class
142 */
143 public static function autoloader( $class ) {
144 $filename = false;
145 if ( strpos( $class, 'SiteOrigin_Panels_Widgets_' ) === 0 ) {
146 $filename = str_replace( 'SiteOrigin_Panels_Widgets_', '', $class );
147 $filename = str_replace( '_', '-', $filename );
148 $filename = strtolower( preg_replace( '/([a-z])([A-Z])/', '$1-$2', $filename ) );
149 $filename = plugin_dir_path( __FILE__ ) . 'inc/widgets/' . $filename . '.php';
150 }
151 elseif ( strpos( $class, 'SiteOrigin_Panels_Compat_' ) === 0 ) {
152 $filename = str_replace( array( 'SiteOrigin_Panels_Compat_', '_' ), array( '', '-' ), $class );
153 $filename = plugin_dir_path( __FILE__ ) . 'compat/' . strtolower( $filename ) . '.php';
154 }
155 elseif ( strpos( $class, 'SiteOrigin_Panels_' ) === 0 ) {
156 $filename = str_replace( array( 'SiteOrigin_Panels_', '_' ), array( '', '-' ), $class );
157 $filename = plugin_dir_path( __FILE__ ) . 'inc/' . strtolower( $filename ) . '.php';
158 }
159
160 if ( ! empty( $filename ) && file_exists( $filename ) ) {
161 include $filename;
162 }
163 }
164
165 public static function activate() {
166 add_option( 'siteorigin_panels_initial_version', SITEORIGIN_PANELS_VERSION, '', 'no' );
167 }
168
169 /**
170 * Initialize SiteOrigin Page Builder
171 *
172 * @action plugins_loaded
173 */
174 public function init() {
175 if (
176 ! is_admin() &&
177 siteorigin_panels_setting( 'sidebars-emulator' ) &&
178 ( ! get_option( 'permalink_structure' ) || get_option( 'rewrite_rules' ) )
179 ) {
180 // Initialize the sidebars emulator.
181 SiteOrigin_Panels_Sidebars_Emulator::single();
182 }
183
184 // Initialize the language.
185 load_plugin_textdomain( 'siteorigin-panels', false, dirname( plugin_basename( __FILE__ ) ) . '/lang/' );
186
187 // Initialize all the extra classes.
188 SiteOrigin_Panels_Home::single();
189
190 // Check if we need to initialize the admin class.
191 if ( is_admin() ) {
192 SiteOrigin_Panels_Admin::single();
193 }
194 }
195
196 /**
197 * Loads Page Builder compatibility to allow other plugins/themes
198 */
199 public function init_compat() {
200 // Compatibility with Widget Options plugin.
201 if ( class_exists( 'WP_Widget_Options' ) ) {
202 require_once plugin_dir_path( __FILE__ ) . 'compat/widget-options.php';
203 }
204
205 // Compatibility with Yoast plugins.
206 if (
207 defined( 'WPSEO_FILE' ) ||
208 function_exists( 'yoast_wpseo_video_seo_init' )
209 ) {
210 require_once plugin_dir_path( __FILE__ ) . 'compat/yoast.php';
211 }
212
213 // Compatibility with AMP plugin.
214 if ( is_admin() && function_exists( 'amp_bootstrap_plugin' ) ) {
215 require_once plugin_dir_path( __FILE__ ) . 'compat/amp.php';
216 }
217
218 // Compatibility with Gravity Forms.
219 if ( class_exists( 'GFCommon' ) ) {
220 require_once plugin_dir_path( __FILE__ ) . 'compat/gravity-forms.php';
221 }
222
223 $load_lazy_load_compat = false;
224 // LazyLoad by WP Rocket.
225 if ( defined( 'ROCKET_LL_VERSION' ) ) {
226 $lazy_load_settings = get_option( 'rocket_lazyload_options' );
227 $load_lazy_load_compat = ! empty( $lazy_load_settings ) && ! empty( $lazy_load_settings['images'] );
228 // WP Rocket.
229 } elseif ( function_exists( 'get_rocket_option' ) && ! defined( 'DONOTROCKETOPTIMIZE' ) ) {
230 $load_lazy_load_compat = get_rocket_option( 'lazyload' ) && apply_filters( 'do_rocket_lazyload', true );
231 }
232
233 if ( apply_filters( 'siteorigin_lazyload_compat', $load_lazy_load_compat ) ) {
234 require_once plugin_dir_path( __FILE__ ) . 'compat/lazy-load-backgrounds.php';
235 }
236
237 if ( siteorigin_panels_setting( 'parallax-type' ) == 'modern' && class_exists( 'Jetpack_Photon' ) && Jetpack::is_module_active( 'photon' ) ) {
238 require_once plugin_dir_path( __FILE__ ) . 'compat/jetpack.php';
239 }
240
241 if ( class_exists( 'Polylang' ) ) {
242 require_once plugin_dir_path( __FILE__ ) . 'compat/polylang.php';
243 }
244 }
245
246 /**
247 * @return mixed|void Are we currently viewing the home page.
248 */
249 public static function is_home() {
250 $home = ( is_front_page() && is_page() && get_option( 'show_on_front' ) == 'page' && get_option( 'page_on_front' ) == get_the_ID() && get_post_meta( get_the_ID(), 'panels_data' ) );
251
252 return apply_filters( 'siteorigin_panels_is_home', $home );
253 }
254
255 /**
256 * Check if we're currently viewing a page builder page.
257 *
258 * @param bool $can_edit Also check if the user can edit this page
259 *
260 * @return bool
261 */
262 public static function is_panel( $can_edit = false ) {
263 // Check if this is a panel
264 $is_panel = ( siteorigin_panels_is_home() || ( is_singular() && get_post_meta( get_the_ID(), 'panels_data', false ) ) );
265
266 return $is_panel && ( ! $can_edit || ( ( is_singular() && current_user_can( 'edit_post', get_the_ID() ) ) || ( siteorigin_panels_is_home() && current_user_can( 'edit_theme_options' ) ) ) );
267 }
268
269 /**
270 * Check if we're in the Live Editor in the frontend.
271 *
272 * @return bool
273 */
274 static function is_live_editor() {
275 return ! empty( $_GET['siteorigin_panels_live_editor'] );
276 }
277
278 public static function preview_url() {
279 global $post, $wp_post_types;
280
281 if (
282 empty( $post ) ||
283 empty( $wp_post_types ) ||
284 empty( $wp_post_types[ $post->post_type ] ) ||
285 ! $wp_post_types[ $post->post_type ]->public
286 ) {
287 $preview_url = add_query_arg(
288 'siteorigin_panels_live_editor',
289 'true',
290 admin_url( 'admin-ajax.php?action=so_panels_live_editor_preview' )
291 );
292 } else {
293 $preview_url = add_query_arg( 'siteorigin_panels_live_editor', 'true', set_url_scheme( get_permalink() ) );
294 }
295 $preview_url = wp_nonce_url( $preview_url, 'live-editor-preview', '_panelsnonce' );
296
297 return $preview_url;
298 }
299
300 public static function container_settings() {
301 $container = array(
302 'selector' => apply_filters( 'siteorigin_panels_theme_container_selector', '' ),
303 'width' => apply_filters( 'siteorigin_panels_theme_container_width', '' ),
304 'full_width' => false,
305 );
306 $container['css_override'] = ! empty( $container['selector'] ) && ! empty( $container['width'] );
307
308 return $container;
309 }
310
311 /**
312 * Get the Page Builder data for the home page.
313 *
314 * @return bool|mixed
315 */
316 public function get_home_page_data() {
317 $page_id = get_option( 'page_on_front' );
318 if ( empty( $page_id ) ) {
319 $page_id = get_option( 'siteorigin_panels_home_page_id' );
320 }
321 if ( empty( $page_id ) ) {
322 return false;
323 }
324
325 $panels_data = get_post_meta( $page_id, 'panels_data', true );
326 if ( is_null( $panels_data ) ) {
327 // Load the default layout
328 $layouts = apply_filters( 'siteorigin_panels_prebuilt_layouts', array() );
329 $panels_data = ! empty( $layouts['default_home'] ) ? $layouts['default_home'] : current( $layouts );
330 }
331
332 return $panels_data;
333 }
334
335 /**
336 * Generate post content for WooCommerce shop page if it's using a PB layout.
337 *
338 * @param $content
339 *
340 * @return string
341 *
342 * @filter woocommerce_format_content
343 */
344 public function generate_woocommerce_content( $content ) {
345 if ( class_exists( 'WooCommerce' ) && is_shop() ) {
346 return $this->generate_post_content( $content );
347 }
348
349 return $content;
350 }
351
352 /**
353 * Generate post content for the current post.
354 *
355 * @param $content
356 *
357 * @return string
358 *
359 * @filter the_content
360 */
361 public function generate_post_content( $content ) {
362 global $post, $preview;
363 if ( empty( $post ) && ! in_the_loop() ) {
364 return $content;
365 }
366
367 if ( ! apply_filters( 'siteorigin_panels_filter_content_enabled', true ) ) {
368 return $content;
369 }
370
371 $post_id = $this->get_post_id();
372
373 // Check if this post has panels_data.
374 if ( get_post_meta( $post_id, 'panels_data', true ) ) {
375 $panel_content = SiteOrigin_Panels::renderer()->render(
376 $post_id,
377 // Add CSS if this is not the main single post, this is handled by add_single_css.
378 $preview || $post_id !== get_queried_object_id()
379 );
380
381 if ( ! empty( $panel_content ) ) {
382 $content = $panel_content;
383
384 if ( ! is_singular() ) {
385 // This is an archive page, so try strip out anything after the more text.
386
387 if ( preg_match( '/<!--more(.*?)?-->/', $content, $matches ) ) {
388 $content = explode( $matches[0], $content, 2 );
389 $content = $content[0];
390 $content = force_balance_tags( $content );
391 if ( ! empty( $matches[1] ) ) {
392 $more_link_text = strip_tags( wp_kses_no_null( trim( $matches[1] ) ) );
393 } else {
394 $more_link_text = __( 'Read More', 'siteorigin-panels' );
395 }
396
397 $more_link = apply_filters( 'the_content_more_link', ' <a href="' . get_permalink() . "#more-{$post->ID}\" class=\"more-link\">$more_link_text</a>", $more_link_text );
398 $content .= '<p>' . $more_link . '</p>';
399 }
400 }
401 }
402 }
403
404 return $content;
405 }
406
407 /**
408 * Generate an excerpt for the current post, if possible.
409 *
410 * @param $text
411 *
412 * @return mixed|string
413 */
414 public function generate_post_excerpt( $text ) {
415 global $post;
416 if ( ( empty( $post ) && ! in_the_loop() ) || $text !== '' ) {
417 return $text;
418 }
419
420 $post_id = $this->get_post_id();
421 $panels_data = get_post_meta( $post_id, 'panels_data', true );
422
423 // If no panels_data is detected, check if the post has blocks.
424 if ( empty( $panels_data ) ) {
425 if ( function_exists( 'has_blocks' ) && has_blocks( get_the_content() ) ) {
426 $parsed_content = parse_blocks( get_the_content() );
427 // Check if the first block is an SO Layout Block, and extract panels_data if it is.
428 if (
429 $parsed_content[0]['blockName'] == 'siteorigin-panels/layout-block' &&
430 isset( $parsed_content[0]['attrs'] ) &&
431 ! empty( $parsed_content[0]['attrs']['panelsData'] )
432 ) {
433 $panels_data = $parsed_content[0]['attrs']['panelsData'];
434 }
435 }
436 }
437
438 if ( $panels_data && ! empty( $panels_data['widgets'] ) ) {
439 $raw_excerpt = '';
440 $excerpt_length = apply_filters( 'excerpt_length', 55 );
441 foreach ( $panels_data['widgets'] as $widget ) {
442 $panels_info = $widget['panels_info'];
443 if ( $panels_info['grid'] > 1 ) {
444 // Limiting search for a text type widget to the first two PB rows to avoid having excerpt content
445 // that's very far down in a post.
446 break;
447 }
448 if ( $panels_info['class'] == 'SiteOrigin_Widget_Editor_Widget' || $panels_info['class'] == 'WP_Widget_Text' || $panels_info['class'] == 'WP_Widget_Black_Studio_TinyMCE' ) {
449 $raw_excerpt .= ' ' . $widget['text'];
450 // This is all effectively default behavior for excerpts, copied from the `wp_trim_excerpt` function.
451 // We're just applying it to text type widgets content in the first two rows.
452 $text = strip_shortcodes( $raw_excerpt );
453 $text = str_replace( ']]>', ']]&gt;', $text );
454 if ( $this->get_localized_word_count( $text ) >= $excerpt_length ) {
455 break;
456 }
457
458 // Check for more quicktag.
459 if ( strpos( $text, '<!--more' ) !== false ) {
460 // Only return everything prior to more quicktag.
461 $raw_excerpt = explode( '<!--more', $text )[0];
462 $excerpt_length = $this->get_localized_word_count( $raw_excerpt );
463 break;
464 }
465 }
466 }
467
468 $text = strip_shortcodes( $raw_excerpt );
469 $text = str_replace( ']]>', ']]&gt;', $text );
470
471 $excerpt_more = apply_filters( 'excerpt_more', ' ' . '[&hellip;]' );
472 $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
473 }
474
475 return $text;
476 }
477
478 private function get_localized_word_count( $text ) {
479
480 // From the core `wp_trim_words` function to get localized word count.
481 $text = wp_strip_all_tags( $text );
482 if ( strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
483 $text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' );
484 preg_match_all( '/./u', $text, $words_array );
485 $words_array = $words_array[0];
486 } else {
487 $words_array = preg_split( "/[\n\r\t ]+/", $text, -1, PREG_SPLIT_NO_EMPTY );
488 }
489
490 return count( $words_array );
491 }
492
493 /**
494 * Generate CSS for the current post
495 */
496 public function generate_post_css() {
497 $post_id = $this->get_post_id();
498
499 if ( is_singular() && get_post_meta( $post_id, 'panels_data', true ) ) {
500 $renderer = SiteOrigin_Panels::renderer();
501 $renderer->add_inline_css( $post_id, $renderer->generate_css( $post_id ) );
502 }
503 }
504
505 /**
506 * Get the post id for the current post.
507 */
508 function get_post_id() {
509
510 $post_id = get_the_ID();
511
512 if ( class_exists( 'WooCommerce' ) && is_shop() ) {
513 $post_id = wc_get_page_id( 'shop' );
514 }
515 global $preview;
516 // If we're viewing a preview make sure we load and render the autosave post's meta.
517 if ( $preview ) {
518 $preview_post = wp_get_post_autosave( $post_id, get_current_user_id() );
519 if ( ! empty( $preview_post ) ) {
520 $post_id = $preview_post->ID;
521 }
522 }
523
524 return $post_id;
525 }
526
527 /**
528 * Add all the necessary body classes.
529 *
530 * @param $classes
531 *
532 * @return array
533 */
534 function body_class( $classes ) {
535 if ( self::is_panel() ) {
536 $classes[] = 'siteorigin-panels';
537 $classes[] = 'siteorigin-panels-before-js';
538
539 add_action( 'wp_footer', array( $this, 'strip_before_js' ), 99 );
540 }
541 if ( self::is_home() ) $classes[] = 'siteorigin-panels-home';
542 if ( self::is_live_editor() ) $classes[] = 'siteorigin-panels-live-editor';
543
544 $this->container = SiteOrigin_Panels::container_settings();
545 if ( ! empty( $this->container ) && $this->container['css_override'] ) {
546 $classes[] = 'siteorigin-panels-css-container';
547 }
548
549 return $classes;
550 }
551
552 /**
553 * Add the Edit Home Page item to the admin bar.
554 *
555 * @param WP_Admin_Bar $admin_bar
556 *
557 * @return WP_Admin_Bar
558 */
559 function admin_bar_menu( $admin_bar ) {
560 // Add the edit home page link
561 if (
562 siteorigin_panels_setting( 'home-page' ) &&
563 current_user_can( 'edit_theme_options' ) &&
564 ( is_home() || is_front_page() )
565 ) {
566 if ( ( is_page() && get_post_meta( get_the_ID(), 'panels_data', true ) !== '' ) || ! is_page() ) {
567 $admin_bar->add_node( array(
568 'id' => 'edit-home-page',
569 'title' => __( 'Edit Home Page', 'siteorigin-panels' ),
570 'href' => admin_url( 'themes.php?page=so_panels_home_page' )
571 ) );
572
573 if ( is_page() ) {
574 // Remove the standard edit button
575 $admin_bar->remove_node( 'edit' );
576 }
577 }
578 }
579
580 // Add a Live Edit link if this is a Page Builder page that the user can edit.
581 if (
582 siteorigin_panels_setting( 'live-editor-quick-link' ) &&
583 is_singular() &&
584 current_user_can( 'edit_post', get_the_ID() ) &&
585 get_post_meta( get_the_ID(), 'panels_data', true )
586 ) {
587 $admin_bar->add_node( array(
588 'id' => 'so_live_editor',
589 'title' => __( 'Live Editor', 'siteorigin-panels' ),
590 'href' => add_query_arg( 'so_live_editor', 1, get_edit_post_link( get_the_ID() ) ),
591 'meta' => array(
592 'class' => 'live-edit-page'
593 )
594 ) );
595
596 add_action( 'wp_enqueue_scripts', array( $this, 'live_edit_link_style' ) );
597 }
598
599 return $admin_bar;
600 }
601
602 function widgets_init() {
603 register_widget( 'SiteOrigin_Panels_Widgets_PostContent' );
604 register_widget( 'SiteOrigin_Panels_Widgets_PostLoop' );
605 register_widget( 'SiteOrigin_Panels_Widgets_Layout' );
606 }
607
608 function live_edit_link_style() {
609 if ( is_singular() && current_user_can( 'edit_post', get_the_ID() ) && get_post_meta( get_the_ID(), 'panels_data', true ) ) {
610 // Add the style for the eye icon before the Live Editor link.
611 $css = '#wpadminbar #wp-admin-bar-so_live_editor > .ab-item:before {
612 content: "\f177";
613 top: 2px;
614 }';
615 wp_add_inline_style( 'siteorigin-panels-front', $css );
616 }
617 }
618
619 /**
620 * Process panels data to make sure everything is properly formatted.
621 *
622 * @param array $panels_data
623 *
624 * @return array
625 */
626 function process_panels_data( $panels_data ) {
627
628 // Process all widgets to make sure that panels_info is properly represented.
629 if ( ! empty( $panels_data['widgets'] ) && is_array( $panels_data['widgets'] ) ) {
630
631 $last_gi = 0;
632 $last_ci = 0;
633 $last_wi = 0;
634
635 foreach ( $panels_data['widgets'] as &$widget ) {
636 // Transfer legacy content
637 if ( empty( $widget['panels_info'] ) && ! empty( $widget['info'] ) ) {
638 $widget['panels_info'] = $widget['info'];
639 unset( $widget['info'] );
640 }
641
642 // Filter the widgets to add indexes.
643 if ( $widget['panels_info']['grid'] != $last_gi ) {
644 $last_gi = $widget['panels_info']['grid'];
645 $last_ci = $widget['panels_info']['cell'];
646 $last_wi = 0;
647 } elseif ( $widget['panels_info']['cell'] != $last_ci ) {
648 $last_ci = $widget['panels_info']['cell'];
649 $last_wi = 0;
650 }
651 $widget['panels_info']['cell_index'] = $last_wi ++;
652 }
653
654 foreach ( $panels_data['grids'] as &$grid ) {
655 if ( ! empty( $grid['style'] ) && is_string( $grid['style'] ) ) {
656 $grid['style'] = array();
657 }
658 }
659 }
660
661 return $panels_data;
662 }
663
664 /**
665 * Fix class names that have been incorrectly escaped.
666 *
667 * @param $class
668 *
669 * @return mixed
670 */
671 public function fix_namespace_escaping( $class ){
672 return preg_replace( '/\\\\+/', '\\', $class );
673 }
674
675 public static function front_css_url() {
676 return self::renderer()->front_css_url();
677 }
678
679 /**
680 * Trigger a siteorigin_panels_version_changed action if the version has changed.
681 */
682 public function version_check() {
683 $active_version = get_option( 'siteorigin_panels_active_version', false );
684 if ( empty( $active_version ) || $active_version !== SITEORIGIN_PANELS_VERSION ) {
685 do_action( 'siteorigin_panels_version_changed' );
686 update_option( 'siteorigin_panels_active_version', SITEORIGIN_PANELS_VERSION );
687 }
688 }
689
690 /**
691 * Script that removes the siteorigin-panels-before-js class from the body.
692 */
693 public function strip_before_js() {
694 ?><script type="text/javascript">document.body.className = document.body.className.replace("siteorigin-panels-before-js","");</script><?php
695 }
696
697 /**
698 * Should we display premium addon messages.
699 *
700 * @return bool
701 */
702 public static function display_premium_teaser() {
703 return siteorigin_panels_setting( 'display-teaser' ) &&
704 apply_filters( 'siteorigin_premium_upgrade_teaser', true ) &&
705 ! defined( 'SITEORIGIN_PREMIUM_VERSION' );
706 }
707
708 /**
709 * Get the premium upgrade URL.
710 *
711 * @return string
712 */
713 public static function premium_url( $featured_addon = false ) {
714 $ref = apply_filters( 'siteorigin_premium_affiliate_id', '' );
715 $url = 'https://siteorigin.com/downloads/premium/?featured_plugin=siteorigin-panels';
716 if ( ! empty( $featured_addon ) ) {
717 $url = add_query_arg( 'featured_addon', urlencode( $featured_addon ), $url );
718 }
719 if ( ! empty( $ref ) ) {
720 $url = add_query_arg( 'ref', urlencode( $ref ), $url );
721 }
722 return $url;
723 }
724
725 /**
726 * Get the registered widget instance by it's class name or the hash generated when it was registered.
727 *
728 * @param $class_or_hash
729 *
730 * @return array
731 */
732 static function get_widget_instance( $class_or_hash ) {
733 global $wp_widget_factory;
734 if ( isset( $wp_widget_factory->widgets[ $class_or_hash ] ) ) {
735 return $wp_widget_factory->widgets[ $class_or_hash ];
736 } else {
737 foreach ( $wp_widget_factory->widgets as $widget_instance ) {
738 if ( $widget_instance instanceof $class_or_hash ) {
739 return $widget_instance;
740 }
741 }
742 }
743 return null;
744 }
745
746 /**
747 * Flag redirect to welcome page after activation.
748 *
749 * @param $plugin
750 */
751 public function activation_flag_redirect( $plugin ) {
752 if ( $plugin == plugin_basename( __FILE__ ) ) {
753 set_transient( 'siteorigin_panels_activation_welcome', true, 30 );
754 }
755 }
756
757 /**
758 * Redirect to a welcome page after activation.
759 */
760 public function activation_do_redirect() {
761 if ( get_transient( 'siteorigin_panels_activation_welcome' ) ) {
762 delete_transient( 'siteorigin_panels_activation_welcome' );
763
764 // Postpone redirect in certain situations
765 if ( ! wp_doing_ajax() && ! is_network_admin() && ! isset( $_GET['activate-multi'] ) ) {
766 delete_transient( 'siteorigin_panels_activation_welcome' );
767 wp_safe_redirect( admin_url( 'options-general.php?page=siteorigin_panels#welcome' ) );
768 exit();
769 }
770 }
771 }
772 }
773
774 SiteOrigin_Panels::single();
775