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 +140 -10 2.14.23 → 2.15.0 View file →
@@ -1,8 +1,9 @@
1 1 <?php
2 2
3 3 namespace ImportWP\Common\Migration;
4 4
5 +use ImportWP\Common\Filesystem\Filesystem;
5 6 use ImportWP\Common\Importer\ImporterManager;
6 7 use ImportWP\Common\Model\ImporterModel;
7 8 use ImportWP\Common\Util\Logger;
8 9 use ImportWP\Container;
@@ -35,8 +36,10 @@
35 36 $this->_migrations[] = array($this, 'migration_06_cron_update');
36 37 $this->_migrations[] = array($this, 'migration_07_add_session_table');
37 38 $this->_migrations[] = array($this, 'migration_08_migrate_taxonomy_settings');
38 39 $this->_migrations[] = array($this, 'migration_09_migrate_attachment_settings');
40 + $this->_migrations[] = array($this, 'migration_10_relative_importer_file_paths');
41 + $this->_migrations[] = array($this, 'migration_11_prefix_custom_methods');
39 42
40 43 $this->_version = count($this->_migrations);
41 44 }
42 45
@@ -708,11 +711,9 @@
708 711 unset($data['settings']['cron_disabled']);
709 712
710 713 $data['settings']['cron'] = $cron;
711 714
712 - remove_filter('content_save_pre', 'wp_filter_post_kses');
713 - wp_update_post(['ID' => $id, 'post_content' => serialize($data)]);
714 - add_filter('content_save_pre', 'wp_filter_post_kses');
715 + $this->update_importer_post_content($id, $data);
715 716 }
716 717 }
717 718
718 719 public function migration_06_cron_update()
@@ -879,12 +880,9 @@
879 880 }
880 881
881 882 $data['map'] = $tmp;
882 883
883 -
884 - remove_filter('content_save_pre', 'wp_filter_post_kses');
885 - wp_update_post(['ID' => $importer['ID'], 'post_content' => serialize($data)]);
886 - add_filter('content_save_pre', 'wp_filter_post_kses');
884 + $this->update_importer_post_content($importer['ID'], $data);
887 885 }
888 886 }
889 887
890 888 // TODO: do we need this? can we get around this with manipulating the data if it exists?
@@ -936,11 +934,143 @@
936 934 }
937 935
938 936 $data['map'] = $tmp;
939 937
938 + $this->update_importer_post_content($importer['ID'], $data);
939 + }
940 + }
940 941
941 - remove_filter('content_save_pre', 'wp_filter_post_kses');
942 - wp_update_post(['ID' => $importer['ID'], 'post_content' => serialize($data)]);
943 - add_filter('content_save_pre', 'wp_filter_post_kses');
942 + /**
943 + * Convert stored absolute importer file paths to uploads-relative paths.
944 + *
945 + * Prevents open_basedir warnings after hosting path / WordPress root changes.
946 + *
947 + * @param bool $migrate_data
948 + * @return void
949 + */
950 + public function migration_10_relative_importer_file_paths($migrate_data = true)
951 + {
952 + if (!$migrate_data) {
953 + return;
944 954 }
955 +
956 + /**
957 + * @var \wpdb $wpdb
958 + */
959 + global $wpdb;
960 +
961 + $results = $wpdb->get_results(
962 + "SELECT meta_id, post_id, meta_key, meta_value
963 + FROM {$wpdb->postmeta}
964 + WHERE meta_key LIKE '\\_importer\\_file\\_%'",
965 + ARRAY_A
966 + );
967 +
968 + if (empty($results)) {
969 + return;
970 + }
971 +
972 + foreach ($results as $row) {
973 + $stored = $row['meta_value'];
974 + if (!Filesystem::is_absolute_path($stored)) {
975 + continue;
976 + }
977 +
978 + $resolved = Filesystem::resolve_importer_file_path($stored);
979 + if (!$resolved) {
980 + continue;
981 + }
982 +
983 + $relative = Filesystem::to_uploads_relative_path($resolved);
984 + if ($relative === '' || $relative === $stored) {
985 + continue;
986 + }
987 +
988 + update_post_meta((int) $row['post_id'], $row['meta_key'], $relative);
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);
945 1075 }
946 1076 }