PluginProbe
Import WP – CSV & XML Import Export for WordPress / 2.15.0
Import WP – CSV & XML Import Export for WordPress v2.15.0
2.15.1 2.15.0 2.14.24 2.14.23 2.7.0 2.7.1 2.7.10 2.7.11 2.7.12 2.7.13 2.7.14 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.9.0 2.9.1 All 144 releases
← All changes | class/Common/Migration/Migrations.php +89 -11 2.14.24 → 2.15.0 View file →
@@ -37,8 +37,9 @@
37 37 $this->_migrations[] = array($this, 'migration_07_add_session_table');
38 38 $this->_migrations[] = array($this, 'migration_08_migrate_taxonomy_settings');
39 39 $this->_migrations[] = array($this, 'migration_09_migrate_attachment_settings');
40 40 $this->_migrations[] = array($this, 'migration_10_relative_importer_file_paths');
41 + $this->_migrations[] = array($this, 'migration_11_prefix_custom_methods');
41 42
42 43 $this->_version = count($this->_migrations);
43 44 }
44 45
@@ -710,11 +711,9 @@
710 711 unset($data['settings']['cron_disabled']);
711 712
712 713 $data['settings']['cron'] = $cron;
713 714
714 - remove_filter('content_save_pre', 'wp_filter_post_kses');
715 - wp_update_post(['ID' => $id, 'post_content' => serialize($data)]);
716 - add_filter('content_save_pre', 'wp_filter_post_kses');
715 + $this->update_importer_post_content($id, $data);
717 716 }
718 717 }
719 718
720 719 public function migration_06_cron_update()
@@ -881,12 +880,9 @@
881 880 }
882 881
883 882 $data['map'] = $tmp;
884 883
885 -
886 - remove_filter('content_save_pre', 'wp_filter_post_kses');
887 - wp_update_post(['ID' => $importer['ID'], 'post_content' => serialize($data)]);
888 - add_filter('content_save_pre', 'wp_filter_post_kses');
884 + $this->update_importer_post_content($importer['ID'], $data);
889 885 }
890 886 }
891 887
892 888 // TODO: do we need this? can we get around this with manipulating the data if it exists?
@@ -938,12 +934,9 @@
938 934 }
939 935
940 936 $data['map'] = $tmp;
941 937
942 -
943 - remove_filter('content_save_pre', 'wp_filter_post_kses');
944 - wp_update_post(['ID' => $importer['ID'], 'post_content' => serialize($data)]);
945 - add_filter('content_save_pre', 'wp_filter_post_kses');
938 + $this->update_importer_post_content($importer['ID'], $data);
946 939 }
947 940 }
948 941
949 942 /**
@@ -993,6 +986,91 @@
993 986 }
994 987
995 988 update_post_meta((int) $row['post_id'], $row['meta_key'], $relative);
996 989 }
990 + }
991 +
992 + /**
993 + * Prefix custom method calls with [iwp:...] so they do not collide with
994 + * shortcodes or Gutenberg content that uses [name(...)].
995 + *
996 + * Rewrites [strtoupper("x")] → [iwp:strtoupper("x")] in importer maps,
997 + * filters, and other stored string settings. Already-prefixed calls are left alone.
998 + *
999 + * @param bool $migrate_data
1000 + * @return void
1001 + */
1002 + public function migration_11_prefix_custom_methods($migrate_data = true)
1003 + {
1004 + if (!$migrate_data) {
1005 + return;
1006 + }
1007 +
1008 + /**
1009 + * @var \wpdb $wpdb
1010 + */
1011 + global $wpdb;
1012 +
1013 + $importers = $wpdb->get_results("SELECT * FROM {$wpdb->posts} WHERE post_type='" . IWP_POST_TYPE . "'", ARRAY_A);
1014 + if (empty($importers)) {
1015 + return;
1016 + }
1017 +
1018 + foreach ($importers as $importer) {
1019 + $data = maybe_unserialize($importer['post_content']);
1020 + if (!is_array($data)) {
1021 + continue;
1022 + }
1023 +
1024 + $migrated = $this->migration_11_prefix_custom_methods_in_value($data);
1025 + if ($migrated === $data) {
1026 + continue;
1027 + }
1028 +
1029 + $this->update_importer_post_content($importer['ID'], $migrated);
1030 + }
1031 + }
1032 +
1033 + /**
1034 + * Persist serialized importer settings without corrupting backslashes.
1035 + *
1036 + * wp_update_post() only slashes the existing DB row, then merges in the
1037 + * caller-supplied fields. Those fields must already be slashed or
1038 + * wp_insert_post() will stripslashes() the payload and break serialize()
1039 + * strings such as the CSV escape character "\".
1040 + *
1041 + * @param int $id
1042 + * @param array $data
1043 + * @return void
1044 + */
1045 + private function update_importer_post_content($id, array $data)
1046 + {
1047 + remove_filter('content_save_pre', 'wp_filter_post_kses');
1048 + wp_update_post([
1049 + 'ID' => $id,
1050 + 'post_content' => wp_slash(serialize($data)),
1051 + ]);
1052 + add_filter('content_save_pre', 'wp_filter_post_kses');
1053 + }
1054 +
1055 + /**
1056 + * Recursively rewrite [method( → [iwp:method( in strings.
1057 + *
1058 + * @param mixed $value
1059 + * @return mixed
1060 + */
1061 + private function migration_11_prefix_custom_methods_in_value($value)
1062 + {
1063 + if (is_array($value)) {
1064 + foreach ($value as $key => $item) {
1065 + $value[$key] = $this->migration_11_prefix_custom_methods_in_value($item);
1066 + }
1067 + return $value;
1068 + }
1069 +
1070 + if (!is_string($value) || $value === '' || strpos($value, '[') === false) {
1071 + return $value;
1072 + }
1073 +
1074 + return preg_replace('/\[(?!iwp:)(\w+)\(/', '[iwp:$1(', $value);
997 1075 }
998 1076 }