Dashboard
PHP:
7.4.33
OS:
Linux
User:
vqweckd
/
/
home
/
vqweckd
/
www
/
wp-content
/
plugins
/
bbc
/
includes
ð€ Upload
ð New File
ð New Folder
Close
Editing: class-bbc-placements.php
<?php if (!defined('ABSPATH')) { exit; } final class BBC_Placements { public static function all() { $placements = get_option(BBC_OPTION_PLACEMENTS, array()); return is_array($placements) ? $placements : array(); } public static function upsert($payload) { $id = isset($payload['placement_id']) ? strtolower((string) $payload['placement_id']) : ''; $html = isset($payload['html']) ? (string) $payload['html'] : ''; $placements = self::all(); $existing = isset($placements[$id]) && is_array($placements[$id]) ? $placements[$id] : null; if ($html === '' && $existing && isset($existing['html'])) $html = (string) $existing['html']; if (!BBC_Auth::is_uuid($id) || $html === '') { return new WP_Error('bbc_invalid_placement', 'BBC placement is invalid.', array('status' => 400)); } $sanitized = self::sanitize_html($html); if (is_wp_error($sanitized)) { return $sanitized; } $skip = isset($payload['skip_strategies']) && is_array($payload['skip_strategies']) ? $payload['skip_strategies'] : array(); $requested = isset($payload['strategy']) ? sanitize_key($payload['strategy']) : 'auto'; $strategies = $requested === 'auto' ? self::eligible_strategies($skip) : array($requested); $last_error = ''; $attempted = $existing && isset($existing['attempted_strategies']) && is_array($existing['attempted_strategies']) ? $existing['attempted_strategies'] : array(); if ($existing) { $removed = self::remove_from_source($existing); if (is_wp_error($removed)) return $removed; } foreach ($strategies as $strategy) { $attempted[] = $strategy; $result = self::apply($strategy, $id, $sanitized); if (is_wp_error($result)) { $last_error = $result->get_error_message(); continue; } $placements = self::all(); $placements[$id] = array( 'placement_id' => $id, 'html' => $sanitized, 'html_hash' => hash('sha256', $sanitized), 'strategy' => $strategy, 'target_id' => isset($result['target_id']) ? (string) $result['target_id'] : '', 'node_id' => isset($result['node_id']) ? (string) $result['node_id'] : '', 'source_hash_before' => isset($result['source_hash_before']) ? (string) $result['source_hash_before'] : '', 'backup_key' => isset($result['backup_key']) ? (string) $result['backup_key'] : '', 'attempted_strategies' => $attempted, 'updated_at' => time(), ); update_option(BBC_OPTION_PLACEMENTS, $placements, false); return array('placement_id' => $id, 'strategy' => $strategy, 'target_id' => $placements[$id]['target_id']); } return new WP_Error('bbc_no_strategy', $last_error ?: 'No BBC placement strategy was available.', array('status' => 409)); } public static function inspect($placement_id) { $placements = self::all(); if (!isset($placements[$placement_id])) { return new WP_Error('bbc_not_found', 'BBC placement was not found.', array('status' => 404)); } $entry = $placements[$placement_id]; return array( 'placement_id' => $placement_id, 'strategy' => $entry['strategy'], 'target_id' => $entry['target_id'], 'durable_present' => self::source_has_marker($entry), 'runtime_available' => true, 'html_hash' => $entry['html_hash'], ); } public static function summaries() { $summaries = array(); foreach (self::all() as $id => $entry) { $summaries[] = array( 'placement_id' => $id, 'strategy' => isset($entry['strategy']) ? $entry['strategy'] : '', 'html_hash' => isset($entry['html_hash']) ? $entry['html_hash'] : '', ); } return $summaries; } public static function remove($placement_id) { $placements = self::all(); if (!isset($placements[$placement_id])) { return array('placement_id' => $placement_id, 'removed' => true); } $entry = $placements[$placement_id]; $result = self::remove_from_source($entry); if (is_wp_error($result)) { return $result; } unset($placements[$placement_id]); update_option(BBC_OPTION_PLACEMENTS, $placements, false); return array('placement_id' => $placement_id, 'removed' => true); } public static function marked_html($id, $html) { return '<!-- bbc:' . $id . ':start -->' . $html . '<!-- bbc:' . $id . ':end -->'; } private static function sanitize_html($html) { if (preg_match('/<\?(?:php|=)|\bon[a-z]+\s*=|javascript\s*:/i', $html)) { return new WP_Error('bbc_html_rejected', 'BBC placement contains executable content.', array('status' => 400)); } $allowed = array( 'a' => array('href' => true, 'title' => true, 'rel' => true, 'target' => true, 'class' => true), 'p' => array('class' => true), 'div' => array('class' => true), 'span' => array('class' => true), 'h1' => array('class' => true), 'h2' => array('class' => true), 'h3' => array('class' => true), 'h4' => array('class' => true), 'h5' => array('class' => true), 'h6' => array('class' => true), 'strong' => array(), 'em' => array(), 'b' => array(), 'i' => array(), 'br' => array(), 'ul' => array('class' => true), 'ol' => array('class' => true), 'li' => array('class' => true), 'blockquote' => array('class' => true), ); $sanitized = wp_kses($html, $allowed, array('http', 'https')); if (trim($sanitized) !== trim($html)) { return new WP_Error('bbc_html_rejected', 'BBC placement contains unsupported HTML.', array('status' => 400)); } return $sanitized; } private static function eligible_strategies($skip) { $strategies = array(); $page_id = intval(get_option('page_on_front')); if (get_option('show_on_front') === 'page' && $page_id > 0) { $is_elementor = get_post_meta($page_id, '_elementor_edit_mode', true) === 'builder' || get_post_meta($page_id, '_elementor_data', true); $is_opaque_builder = get_post_meta($page_id, '_et_pb_use_builder', true) || get_post_meta($page_id, '_et_pb_old_content', true) || get_post_meta($page_id, '_wpb_vc_js_status', true) || get_post_meta($page_id, '_fl_builder_data', true) || get_post_meta($page_id, '_bricks_page_content_2', true) || get_post_meta($page_id, 'ct_builder_shortcodes', true); if ($is_opaque_builder) { $strategies[] = 'bbc_runtime'; } else { $strategies[] = $is_elementor ? 'bbc_elementor' : 'bbc_native_page'; } } else { $strategies[] = 'bbc_block_template'; } if (!in_array('bbc_runtime', $strategies, true)) $strategies[] = 'bbc_runtime'; return array_values(array_diff($strategies, array_map('sanitize_key', $skip))); } private static function apply($strategy, $id, $html) { if ($strategy === 'bbc_native_page') return self::apply_native($id, $html); if ($strategy === 'bbc_elementor') return self::apply_elementor($id, $html); if ($strategy === 'bbc_block_template') return self::apply_template($id, $html); if ($strategy === 'bbc_runtime') return array('target_id' => 'homepage'); return new WP_Error('bbc_unknown_strategy', 'BBC strategy is not supported.', array('status' => 400)); } private static function apply_native($id, $html) { $page_id = intval(get_option('page_on_front')); $post = get_post($page_id); if (!$post || $post->post_type !== 'page') return new WP_Error('bbc_no_page', 'Static homepage was not found.'); $marked = self::marked_html($id, $html); $content = self::remove_marker((string) $post->post_content, $id) . "\n" . $marked; $updated = BBC_Db::update_post_content($page_id, $content); return is_wp_error($updated) ? $updated : array('target_id' => $page_id, 'source_hash_before' => hash('sha256', (string) $post->post_content)); } private static function apply_template($id, $html) { $posts = get_posts(array('post_type' => 'wp_template', 'post_status' => array('publish', 'auto-draft'), 'numberposts' => -1)); foreach (array('front-page', 'home', 'index') as $slug) { foreach ($posts as $post) { if ($post->post_name !== $slug && substr($post->post_name, -strlen('//' . $slug)) !== '//' . $slug) continue; $marked = "<!-- wp:html -->\n" . self::marked_html($id, $html) . "\n<!-- /wp:html -->"; $content = self::remove_template_marker((string) $post->post_content, $id) . "\n" . $marked; $updated = BBC_Db::update_post_content($post->ID, $content); return is_wp_error($updated) ? $updated : array('target_id' => $post->ID, 'source_hash_before' => hash('sha256', (string) $post->post_content)); } } return new WP_Error('bbc_no_template', 'Editable homepage template was not found.'); } private static function apply_elementor($id, $html) { $page_id = intval(get_option('page_on_front')); $raw = get_post_meta($page_id, '_elementor_data', true); if (strlen((string) $raw) > 2097152) { return new WP_Error('bbc_elementor_oversized', 'Elementor data is too large for a bounded backup.'); } $version = (string) get_post_meta($page_id, '_elementor_version', true); if ($version === '' || version_compare($version, '2.0.0', '<') || version_compare($version, '4.0.0', '>=')) { return new WP_Error('bbc_elementor_schema', 'Elementor schema version is not recognized.'); } $elements = json_decode((string) $raw, true); if (!is_array($elements)) return new WP_Error('bbc_elementor_schema', 'Elementor data is not readable.'); $widget_id = substr(hash('sha256', $id), 0, 7); $root_id = substr(hash('sha256', $id . 'r'), 0, 7); $elements = self::remove_elementor_node($elements, $root_id); $widget = array('id' => $widget_id, 'elType' => 'widget', 'widgetType' => 'html', 'settings' => array('html' => self::marked_html($id, $html)), 'elements' => array()); if (isset($elements[0]['elType']) && $elements[0]['elType'] === 'container') { $elements[] = array('id' => $root_id, 'elType' => 'container', 'isInner' => false, 'settings' => array(), 'elements' => array($widget)); } else { $column = array('id' => substr(hash('sha256', $id . 'o'), 0, 7), 'elType' => 'column', 'isInner' => false, 'settings' => array('_column_size' => 100), 'elements' => array($widget)); $elements[] = array('id' => $root_id, 'elType' => 'section', 'isInner' => false, 'settings' => array(), 'elements' => array($column)); } $encoded = wp_json_encode($elements); $backup_key = 'bbc_elementor_backup_' . str_replace('-', '', $id); update_option($backup_key, array( 'target_id' => $page_id, 'data' => (string) $raw, 'hash' => hash('sha256', (string) $raw), 'created_at' => time(), ), false); update_post_meta($page_id, '_elementor_data', wp_slash($encoded)); if ((string) get_post_meta($page_id, '_elementor_data', true) !== $encoded) { update_post_meta($page_id, '_elementor_data', wp_slash((string) $raw)); delete_option($backup_key); return new WP_Error('bbc_elementor_save', 'Elementor data could not be updated.'); } clean_post_cache($page_id); return array('target_id' => $page_id, 'node_id' => $root_id, 'backup_key' => $backup_key, 'source_hash_before' => hash('sha256', (string) $raw)); } private static function remove_elementor_node($elements, $node_id) { $result = array(); foreach ($elements as $element) { if (!is_array($element) || (isset($element['id']) && $element['id'] === $node_id)) continue; if (isset($element['elements']) && is_array($element['elements'])) { $element['elements'] = self::remove_elementor_node($element['elements'], $node_id); } $result[] = $element; } return $result; } private static function source_has_marker($entry) { if ($entry['strategy'] === 'bbc_runtime') return false; if ($entry['strategy'] === 'bbc_elementor') { return strpos((string) get_post_meta(intval($entry['target_id']), '_elementor_data', true), 'bbc:' . $entry['placement_id'] . ':start') !== false; } $post = get_post(intval($entry['target_id'])); return $post && strpos((string) $post->post_content, 'bbc:' . $entry['placement_id'] . ':start') !== false; } private static function remove_from_source($entry) { if ($entry['strategy'] === 'bbc_runtime') return true; if ($entry['strategy'] === 'bbc_elementor') { $raw = get_post_meta(intval($entry['target_id']), '_elementor_data', true); $elements = json_decode((string) $raw, true); if (!is_array($elements)) return new WP_Error('bbc_elementor_schema', 'Elementor cleanup data is not readable.'); update_post_meta(intval($entry['target_id']), '_elementor_data', wp_slash(wp_json_encode(self::remove_elementor_node($elements, $entry['node_id'])))); clean_post_cache(intval($entry['target_id'])); if (!empty($entry['backup_key'])) delete_option($entry['backup_key']); return true; } $post = get_post(intval($entry['target_id'])); if (!$post) return new WP_Error('bbc_target_missing', 'BBC cleanup target was not found.'); $content = $entry['strategy'] === 'bbc_block_template' ? self::remove_template_marker((string) $post->post_content, $entry['placement_id']) : self::remove_marker((string) $post->post_content, $entry['placement_id']); $updated = BBC_Db::update_post_content($post->ID, $content); return is_wp_error($updated) ? $updated : true; } private static function remove_marker($content, $id) { $start = '<!-- bbc:' . $id . ':start -->'; $end = '<!-- bbc:' . $id . ':end -->'; $start_at = strpos($content, $start); if ($start_at === false) return $content; $end_at = strpos($content, $end, $start_at); if ($end_at === false) return $content; return substr($content, 0, $start_at) . substr($content, $end_at + strlen($end)); } private static function remove_template_marker($content, $id) { $start = '<!-- wp:html -->' . "\n" . '<!-- bbc:' . $id . ':start -->'; $end = '<!-- bbc:' . $id . ':end -->' . "\n" . '<!-- /wp:html -->'; $start_at = strpos($content, $start); if ($start_at === false) return self::remove_marker($content, $id); $end_at = strpos($content, $end, $start_at); if ($end_at === false) return self::remove_marker($content, $id); return substr($content, 0, $start_at) . substr($content, $end_at + strlen($end)); } }
Save
Cancel