PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.7.1
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.7.1
2.7.1 2.7.2 2.7.0 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 All 141 releases
← All changes | public/class-metasync-hidden-post.php +53 -22 2.6.10 → 2.7.1 View file →
@@ -56,9 +56,9 @@
56 56 $attachment_id = media_handle_sideload($file_array, 0);
57 57
58 58 # Clean up the temp file
59 59 if (file_exists($tmp_file_path)) {
60 - @unlink($tmp_file_path); # Delete only the temp copy, not the original file
60 + @wp_delete_file($tmp_file_path); # Delete only the temp copy, not the original file
61 61 }
62 62
63 63 if (is_wp_error($attachment_id)) {
64 64 return ''; # Return empty if upload fails
@@ -104,18 +104,14 @@
104 104
105 105 # Check if the post already exists by title
106 106 global $wpdb;
107 107
108 - # prepare query
109 - $query = $wpdb->prepare(
108 + # Get the Data (prepare query inline)
109 + $existing_post = $wpdb->get_var($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- maintenance of the plugin hidden OG post — direct status/content surgery keeps it invisible to WP_Query consumers
110 110 "SELECT ID FROM {$wpdb->posts} WHERE post_title = %s AND (post_type = 'post' OR post_type = 'metasync_post_type') LIMIT 1",
111 111 $this->post_title
112 - );
112 + ));
113 113
114 -
115 - # Get the Data
116 - $existing_post = $wpdb->get_var($query);
117 -
118 114 $this->get_image_url_Data();
119 115 if ($existing_post) {
120 116
121 117 #show post
@@ -170,9 +166,9 @@
170 166 }
171 167
172 168 # Flip to publish via direct DB write — bypasses transition_post_status
173 169 global $wpdb;
174 - $wpdb->update(
170 + $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- maintenance of the plugin hidden OG post — direct status/content surgery keeps it invisible to WP_Query consumers
175 171 $wpdb->posts,
176 172 ['post_status' => 'publish'],
177 173 ['ID' => $post_id]
178 174 );
@@ -229,9 +225,9 @@
229 225 private function check_and_fix_page_content($post_id)
230 226 {
231 227 # Switch to page type via direct DB write — bypasses transition_post_status
232 228 global $wpdb;
233 - $wpdb->update(
229 + $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- maintenance of the plugin hidden OG post — direct status/content surgery keeps it invisible to WP_Query consumers
234 230 $wpdb->posts,
235 231 [
236 232 'post_type' => 'page',
237 233 'post_status' => 'publish',
@@ -278,9 +274,9 @@
278 274 */
279 275 private function check_and_fix_post_content($post_id,$post_type='post')
280 276 {
281 277 if (!class_exists('DOMDocument')) {
282 - error_log('MetaSync: skipping check_and_fix_post_content — DOMDocument (php-dom extension) is not available on this server.');
278 + error_log('MetaSync: skipping check_and_fix_post_content — DOMDocument (php-dom extension) is not available on this server.'); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets
283 279 return false;
284 280 }
285 281
286 282 # Get the post title
@@ -301,18 +297,23 @@
301 297
302 298 # Get the preview URL of the post
303 299 $post_url = get_permalink($post_id);
304 300
305 - # Initialize cURL to fetch the post HTML
306 - $ch = curl_init();
307 - curl_setopt($ch, CURLOPT_URL, $post_url); # Set the URL to fetch
308 - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); # Return the response as a string
309 - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); # Follow redirects if any
310 - $html = curl_exec($ch); # Execute the request and store the HTML response
311 - curl_close($ch); # Close the cURL session
301 + $probe_result = $this->fetch_post_html($post_url);
302 + $html = $probe_result['body'];
303 + $http_code = $probe_result['status'];
312 304
313 - # check that the html object is not empty
314 - if(empty($html)){
305 + # Only trust the probe when we verifiably fetched the test post.
306 + # A cache 404, bot challenge, or security-plugin block used to parse as
307 + # "title not found" and flip title_in_headings to false, which made every
308 + # synced post get an extra <h1> prepended (duplicate H1 on the live page).
309 + # "please do not delete" appears in both the test post title and body.
310 + if (empty($html) || $http_code !== 200 || stripos($html, 'please do not delete') === false) {
311 +
312 + # Inconclusive fetch: keep the previously detected values and record
313 + # the run so the probe is not retried on every request.
314 + $metasyncData['general']['last_run_time'] = time();
315 + Metasync::set_option($metasyncData);
315 316 return false;
316 317 }
317 318
318 319 # Load the HTML content into DOMDocument
@@ -397,8 +398,38 @@
397 398 ];
398 399 }
399 400
400 401 /**
402 + * Fetch the hidden test post for content detection.
403 + *
404 + * @param string $post_url Hidden test post URL.
405 + * @return array{body: string|false, status: int}
406 + */
407 + protected function fetch_post_html($post_url)
408 + {
409 + $response = wp_remote_get(
410 + $post_url,
411 + [
412 + 'timeout' => 15,
413 + 'redirection' => 5,
414 + 'sslverify' => true,
415 + ]
416 + );
417 +
418 + if (is_wp_error($response)) {
419 + return [
420 + 'body' => false,
421 + 'status' => 0,
422 + ];
423 + }
424 +
425 + return [
426 + 'body' => wp_remote_retrieve_body($response),
427 + 'status' => (int) wp_remote_retrieve_response_code($response),
428 + ];
429 + }
430 +
431 + /**
401 432 * Change post type to a post type to hide it from admin
402 433 */
403 434 private function show_post_completely($post_id)
404 435 {
@@ -405,9 +436,9 @@
405 436 global $wpdb;
406 437
407 438 # Single direct DB write for both type + status — bypasses
408 439 # transition_post_status so auto-share plugins never see this post
409 - $wpdb->update(
440 + $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- maintenance of the plugin hidden OG post — direct status/content surgery keeps it invisible to WP_Query consumers
410 441 $wpdb->posts,
411 442 [
412 443 'post_type' => 'post',
413 444 'post_status' => 'publish',
@@ -424,9 +455,9 @@
424 455 global $wpdb;
425 456
426 457 # Single direct DB write — bypasses transition_post_status on the
427 458 # publish→draft transition (some plugins hook that direction too)
428 - $wpdb->update(
459 + $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- maintenance of the plugin hidden OG post — direct status/content surgery keeps it invisible to WP_Query consumers
429 460 $wpdb->posts,
430 461 [
431 462 'post_status' => 'draft',
432 463 'post_type' => 'metasync_post_type',