| @@ -117,9 +117,9 @@ | ||
| 117 | 117 | * stable to match against. |
| 118 | 118 | */ |
| 119 | 119 | public function maybe_enqueue_editor_assets() |
| 120 | 120 | { |
| 121 | - $page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : ''; | |
| 121 | + $page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only page check to enqueue editor assets | |
| 122 | 122 | |
| 123 | 123 | if ($page !== $this->get_editor_page_slug()) { |
| 124 | 124 | return; |
| 125 | 125 | } |
| @@ -279,8 +279,9 @@ | ||
| 279 | 279 | |
| 280 | 280 | $actions['edit_html'] = sprintf( |
| 281 | 281 | '<a href="%s" title="%s">%s</a>', |
| 282 | 282 | esc_url($edit_url), |
| 283 | + /* translators: %s: company name (whitelabel-aware). */ | |
| 283 | 284 | esc_attr(sprintf(__('Edit with %s Visual Editor', 'metasync'), $label)), |
| 284 | 285 | __('Edit HTML', 'metasync') |
| 285 | 286 | ); |
| 286 | 287 | |
| @@ -292,8 +293,9 @@ | ||
| 292 | 293 | */ |
| 293 | 294 | public function add_editor_page() |
| 294 | 295 | { |
| 295 | 296 | $label = Metasync::get_whitelabel_company_name() ?: 'SearchAtlas'; |
| 297 | + /* translators: %s: company name (whitelabel-aware). */ | |
| 296 | 298 | $page_title = sprintf(__('%s HTML Editor', 'metasync'), $label); |
| 297 | 299 | |
| 298 | 300 | add_submenu_page( |
| 299 | 301 | '', // Hidden from menu |
| @@ -311,20 +313,20 @@ | ||
| 311 | 313 | public function render_editor_page() |
| 312 | 314 | { |
| 313 | 315 | // Check permissions |
| 314 | 316 | if (!current_user_can('edit_pages')) { |
| 315 | - wp_die(__('You do not have sufficient permissions to access this page.', 'metasync')); | |
| 317 | + wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'metasync')); | |
| 316 | 318 | } |
| 317 | 319 | |
| 318 | 320 | // Get post ID |
| 319 | - $post_id = isset($_GET['post_id']) ? intval($_GET['post_id']) : 0; | |
| 321 | + $post_id = isset($_GET['post_id']) ? intval($_GET['post_id']) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only post ID, capability checked, view only | |
| 320 | 322 | |
| 321 | 323 | if (!$post_id) { |
| 322 | - wp_die(__('Invalid page ID.', 'metasync')); | |
| 324 | + wp_die(esc_html__('Invalid page ID.', 'metasync')); | |
| 323 | 325 | } |
| 324 | 326 | |
| 325 | 327 | if (!current_user_can('edit_post', $post_id)) { |
| 326 | - wp_die(__('You do not have sufficient permissions to access this page.', 'metasync')); | |
| 328 | + wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'metasync')); | |
| 327 | 329 | } |
| 328 | 330 | |
| 329 | 331 | // Get post |
| 330 | 332 | $post = get_post($post_id); |
| @@ -329,9 +331,9 @@ | ||
| 329 | 331 | // Get post |
| 330 | 332 | $post = get_post($post_id); |
| 331 | 333 | |
| 332 | 334 | if (!$post) { |
| 333 | - wp_die(__('Page not found.', 'metasync')); | |
| 335 | + wp_die(esc_html__('Page not found.', 'metasync')); | |
| 334 | 336 | } |
| 335 | 337 | |
| 336 | 338 | // Check if raw HTML is enabled |
| 337 | 339 | $has_raw_html = get_post_meta($post_id, '_metasync_raw_html_enabled', true); |
| @@ -336,9 +338,9 @@ | ||
| 336 | 338 | // Check if raw HTML is enabled |
| 337 | 339 | $has_raw_html = get_post_meta($post_id, '_metasync_raw_html_enabled', true); |
| 338 | 340 | |
| 339 | 341 | if (!$has_raw_html) { |
| 340 | - wp_die(__('This page is not a raw HTML page.', 'metasync')); | |
| 342 | + wp_die(esc_html__('This page is not a raw HTML page.', 'metasync')); | |
| 341 | 343 | } |
| 342 | 344 | |
| 343 | 345 | // LPS pages are owned by the importer and are always complete |
| 344 | 346 | // documents, so the canvas is refused outright rather than opened in a |
| @@ -459,9 +461,9 @@ | ||
| 459 | 461 | $editor_style_deps, |
| 460 | 462 | $this->version |
| 461 | 463 | ); |
| 462 | 464 | |
| 463 | - $post_id = isset($_GET['post_id']) ? intval($_GET['post_id']) : 0; | |
| 465 | + $post_id = isset($_GET['post_id']) ? intval($_GET['post_id']) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only post ID passed to script data | |
| 464 | 466 | |
| 465 | 467 | // Localize script with data |
| 466 | 468 | wp_localize_script('metasync-html-editor', 'metasyncEditor', array( |
| 467 | 469 | 'ajax_url' => admin_url('admin-ajax.php'), |
| @@ -494,8 +496,9 @@ | ||
| 494 | 496 | 'load_failed_title' => __('The visual editor could not start', 'metasync'), |
| 495 | 497 | 'load_failed_core' => __('The visual editor library could not be loaded, so this page cannot be edited visually. Reload the page, and if the problem continues check whether a browser extension, proxy or content security policy is blocking plugin scripts.', 'metasync'), |
| 496 | 498 | 'load_failed_blocks' => __('The editor loaded, but its extra block library is unavailable, so the Blocks panel only offers the built-in blocks. Existing page content can still be edited and saved normally.', 'metasync'), |
| 497 | 499 | 'load_failed_init' => __('The visual editor failed to start while loading this page. Reload to try again; the saved page content has not been changed.', 'metasync'), |
| 500 | + /* translators: %s: name of the missing component. */ | |
| 498 | 501 | 'load_failed_detail' => __('Missing component: %s', 'metasync'), |
| 499 | 502 | 'reload' => __('Reload page', 'metasync'), |
| 500 | 503 | 'dismiss' => __('Dismiss', 'metasync'), |
| 501 | 504 | 'save_disabled' => __('Saving is disabled because the editor did not load', 'metasync'), |
| @@ -579,8 +582,9 @@ | ||
| 579 | 582 | // the browser did. Both checks read the value already in the database, |
| 580 | 583 | // not the payload: what matters is whether the page being overwritten |
| 581 | 584 | // is one the canvas could have represented faithfully. |
| 582 | 585 | if (self::is_lps_page($post_id)) { |
| 586 | + Metasync_PostHog::rollup('visual_editor_saved', array('blocked_lps' => 1)); | |
| 583 | 587 | wp_send_json_error( |
| 584 | 588 | array('message' => __('This page was imported from Website Studio and cannot be saved from the visual editor.', 'metasync')), |
| 585 | 589 | 409 |
| 586 | 590 | ); |
| @@ -588,8 +592,9 @@ | ||
| 588 | 592 | |
| 589 | 593 | $stored = get_post_meta($post_id, '_metasync_raw_html_content', true); |
| 590 | 594 | |
| 591 | 595 | if (self::is_unsafe_for_visual_editor($stored)) { |
| 596 | + Metasync_PostHog::rollup('visual_editor_saved', array('blocked_full_document' => 1)); | |
| 592 | 597 | wp_send_json_error( |
| 593 | 598 | array('message' => __('This page is a complete HTML document, so saving it from the visual editor would discard its doctype, head and scripts. Use Edit HTML Directly on the page editor instead.', 'metasync')), |
| 594 | 599 | 409 |
| 595 | 600 | ); |
| @@ -616,8 +621,11 @@ | ||
| 616 | 621 | 'ID' => $post_id, |
| 617 | 622 | 'post_modified' => current_time('mysql'), |
| 618 | 623 | 'post_modified_gmt' => current_time('mysql', 1) |
| 619 | 624 | )); |
| 625 | + | |
| 626 | + // Consent-gated analytics: daily counts, not one event per save. | |
| 627 | + Metasync_PostHog::rollup('visual_editor_saved', array('saved' => 1)); | |
| 620 | 628 | |
| 621 | 629 | wp_send_json_success(array( |
| 622 | 630 | 'message' => __('Page saved successfully', 'metasync'), |
| 623 | 631 | 'preview_url' => get_permalink($post_id) |