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( ']]>', ']]>', $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( ']]>', ']]>', $text ); |
| 470 | |
| 471 | $excerpt_more = apply_filters( 'excerpt_more', ' ' . '[…]' ); |
| 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 |