get_results( "SELECT meta_id, post_id, meta_key, meta_value FROM {$wpdb->postmeta} WHERE meta_key IN ('" . implode("','", $keys) . "')" ); $patched = 0; $touched_posts = 0; foreach ($rows as $row) { $val = $row->meta_value; if (! is_string($val) || $val === '') continue; $is_json = ($val[0] === '['); $elements = null; if ($is_json) { $elements = json_decode($val, true); } else { // Mirror keys (_bricks_page_header_2, _bricks_page_footer_2) are stored as // PHP-serialized arrays by av-bricks-rest-bridge → maybe_unserialize. $maybe = @unserialize($val); if (is_array($maybe)) $elements = $maybe; } if (! is_array($elements)) continue; $count = 0; av_walk_fix_links($elements, $count); if ($count === 0) continue; // Write back in same format as it was stored $new = $is_json ? wp_json_encode($elements) : maybe_serialize($elements); $wpdb->update($wpdb->postmeta, ['meta_value' => $new], ['meta_id' => $row->meta_id], ['%s'], ['%d']); wp_cache_delete($row->post_id, 'post_meta'); $patched += $count; $touched_posts++; $fmt = $is_json ? 'json' : 'serialized'; echo "post #{$row->post_id} ({$row->meta_key}, $fmt) : $count link(s) patched\n"; } echo "\nTotal : $patched links across $touched_posts post(s) patched (type internal\u{2192}external).\n"; exit; }); function av_walk_fix_links(&$elements, &$count) { $walk = function (&$node) use (&$walk, &$count) { if (! is_array($node)) return; // Link block shape : has type and url, type wrongly set to 'internal' with a non-numeric url if (isset($node['type']) && $node['type'] === 'internal' && isset($node['url']) && is_string($node['url']) && $node['url'] !== '') { $node['type'] = 'external'; $count++; } foreach ($node as &$value) { if (is_array($value)) $walk($value); } }; foreach ($elements as &$el) $walk($el); }