| @@ -4,9 +4,8 @@ | ||
| 4 | 4 | |
| 5 | 5 | use ImportWP\Common\Importer\Exception\MapperException; |
| 6 | 6 | use ImportWP\Common\Importer\MapperInterface; |
| 7 | 7 | use ImportWP\Common\Importer\ParsedData; |
| 8 | -use ImportWP\Common\Importer\Template\TemplateManager; | |
| 9 | 8 | use ImportWP\Common\Util\Logger; |
| 10 | 9 | |
| 11 | 10 | class UserMapper extends AbstractMapper implements MapperInterface |
| 12 | 11 | { |
| @@ -41,48 +40,51 @@ | ||
| 41 | 40 | } |
| 42 | 41 | |
| 43 | 42 | public function exists(ParsedData $data) |
| 44 | 43 | { |
| 45 | - $unique_fields = TemplateManager::get_template_unique_fields($this->template); | |
| 44 | + list($unique_fields, $meta_args, $has_unique_field) = $this->exists_get_identifier($data); | |
| 45 | + if (!empty($meta_args)) { | |
| 46 | + foreach ($meta_args as &$meta_arg_v) { | |
| 47 | + $meta_arg_v['compare'] = '='; | |
| 48 | + $meta_arg_v['type'] = 'CHAR'; | |
| 49 | + } | |
| 50 | + } | |
| 46 | 51 | |
| 47 | - $unique_fields = $this->getUniqueIdentifiers($unique_fields); | |
| 48 | - $unique_fields = apply_filters('iwp/template_unique_fields', $unique_fields, $this->template, $this->importer); | |
| 49 | - | |
| 50 | 52 | $unique_field_found = false; |
| 51 | 53 | |
| 52 | - $default_group = $data->getData('default'); | |
| 53 | 54 | $query_args = array(); |
| 54 | - $meta_args = array(); | |
| 55 | 55 | $search = array(); // store search values |
| 56 | 56 | $search_columns = array(); // store search columns |
| 57 | 57 | |
| 58 | - $has_unique_field = false; | |
| 58 | + if (!$has_unique_field) { | |
| 59 | + foreach ($unique_fields as $field) { | |
| 59 | 60 | |
| 60 | - foreach ($unique_fields as $field) { | |
| 61 | + // check all groups for a unique value | |
| 62 | + $unique_value = $this->find_unique_field_in_data($data, $field); | |
| 61 | 63 | |
| 62 | - // check all groups for a unique value | |
| 63 | - $unique_value = $data->getValue($field, '*'); | |
| 64 | - if (!empty($unique_value)) { | |
| 65 | - $has_unique_field = true; | |
| 64 | + if ($this->has_identifier_value($unique_value)) { | |
| 65 | + $has_unique_field = true; | |
| 66 | 66 | |
| 67 | - if (in_array($field, $this->_user_fields)) { | |
| 68 | - $search_columns[] = $field; | |
| 69 | - $search[] = $default_group[$field]; | |
| 70 | - } else { | |
| 71 | - $meta_args[] = array( | |
| 72 | - 'key' => $field, | |
| 73 | - 'value' => $default_group[$field], | |
| 74 | - 'compare' => '=', | |
| 75 | - 'type' => 'CHAR' | |
| 76 | - ); | |
| 67 | + if (in_array($field, ['ID', 'user_login', 'user_nicename', 'user_email', 'user_url'])) { | |
| 68 | + $search_columns[] = $field; | |
| 69 | + $search[] = $unique_value; | |
| 70 | + } else { | |
| 71 | + $meta_args[] = array( | |
| 72 | + 'key' => $field, | |
| 73 | + 'value' => $unique_value, | |
| 74 | + 'compare' => '=', | |
| 75 | + 'type' => 'CHAR' | |
| 76 | + ); | |
| 77 | + } | |
| 78 | + $unique_field_found = $field; | |
| 79 | + $this->set_unique_identifier_settings($unique_field_found, $unique_value); | |
| 80 | + break; | |
| 77 | 81 | } |
| 78 | - $unique_field_found = $field; | |
| 79 | - break; | |
| 80 | 82 | } |
| 81 | 83 | } |
| 82 | 84 | |
| 83 | 85 | if (!$has_unique_field) { |
| 84 | - throw new MapperException("No Unique fields present."); | |
| 86 | + throw new MapperException(__('No unique identifier value present. Check that Permissions has a unique identifier set and this row has a non-empty value. File column references are stored as _iwp_ref_uid.', 'jc-importer')); | |
| 85 | 87 | } |
| 86 | 88 | |
| 87 | 89 | // create search |
| 88 | 90 | $query_args['search'] = implode(', ', $search); |
| @@ -87,16 +89,63 @@ | ||
| 87 | 89 | // create search |
| 88 | 90 | $query_args['search'] = implode(', ', $search); |
| 89 | 91 | $query_args['search_columns'] = $search_columns; |
| 90 | 92 | $query_args['meta_query'] = $meta_args; |
| 93 | + $query_args = apply_filters('iwp/importer/mapper/user_exists_query', $query_args); | |
| 94 | + Logger::debug("UserMapper::exists -query=" . wp_json_encode($query_args)); | |
| 91 | 95 | $query = new \WP_User_Query($query_args); |
| 92 | 96 | |
| 97 | + // if we are on a multisite instance and user has not been found. | |
| 98 | + if (is_multisite() && $query->get_total() == 0) { | |
| 99 | + | |
| 100 | + // get list of sites except this one | |
| 101 | + $sites = get_sites([ | |
| 102 | + 'site__not_in' => get_current_blog_id(), | |
| 103 | + 'fields' => 'ids' | |
| 104 | + ]); | |
| 105 | + | |
| 106 | + foreach ($sites as $site) { | |
| 107 | + | |
| 108 | + // do user search on each site | |
| 109 | + switch_to_blog($site); | |
| 110 | + $query = new \WP_User_Query($query_args); | |
| 111 | + restore_current_blog(); | |
| 112 | + | |
| 113 | + $total = $query->get_total(); | |
| 114 | + if ($total > 1) { | |
| 115 | + | |
| 116 | + $ids = []; | |
| 117 | + foreach ($query->results as $result) { | |
| 118 | + $ids[] = $result->ID; | |
| 119 | + } | |
| 120 | + throw new MapperException(sprintf(__("Record is not unique: %s, Matching Ids: (%s).", 'jc-importer'), $unique_field_found, implode(', ', $ids))); | |
| 121 | + } elseif ($total == 1) { | |
| 122 | + | |
| 123 | + // if we have 1 result then add the user to our site. | |
| 124 | + | |
| 125 | + $role = $query->results[0]->roles[0]; | |
| 126 | + if ($this->importer->isEnabledField('user.role')) { | |
| 127 | + $tmp_role = $data->getValue('role'); | |
| 128 | + if (!empty($tmp_role)) { | |
| 129 | + $role = $tmp_role; | |
| 130 | + } | |
| 131 | + } | |
| 132 | + | |
| 133 | + $result = add_user_to_blog(get_current_blog_id(), $query->results[0]->ID, $role); | |
| 134 | + if (is_wp_error($result)) { | |
| 135 | + throw new MapperException($result->get_error_message()); | |
| 136 | + } | |
| 137 | + break; | |
| 138 | + } | |
| 139 | + } | |
| 140 | + } | |
| 141 | + | |
| 93 | 142 | if ($query->total_users > 1) { |
| 94 | 143 | $ids = []; |
| 95 | 144 | foreach ($query->results as $result) { |
| 96 | 145 | $ids[] = $result->ID; |
| 97 | 146 | } |
| 98 | - throw new MapperException("Record is not unique: " . $unique_field_found . ", Matching Ids: (" . implode(', ', $ids) . ")."); | |
| 147 | + throw new MapperException(sprintf(__("Record is not unique: %s, Matching Ids: (%s).", 'jc-importer'), $unique_field_found, implode(', ', $ids))); | |
| 99 | 148 | } |
| 100 | 149 | |
| 101 | 150 | if ($query->total_users == 1) { |
| 102 | 151 | $this->ID = $query->results[0]->ID; |
| @@ -125,17 +174,17 @@ | ||
| 125 | 174 | } |
| 126 | 175 | } |
| 127 | 176 | |
| 128 | 177 | if (!isset($core['user_login']) || empty($core['user_login'])) { |
| 129 | - throw new MapperException("No username present"); | |
| 178 | + throw new MapperException(__("No username present", 'jc-importer')); | |
| 130 | 179 | } |
| 131 | 180 | |
| 132 | 181 | if (!isset($core['user_pass']) || empty($core['user_pass'])) { |
| 133 | - throw new MapperException("No password present"); | |
| 182 | + throw new MapperException(__("No password present", 'jc-importer')); | |
| 134 | 183 | } |
| 135 | 184 | |
| 136 | 185 | if (!empty($core['user_email']) && !is_email($core['user_email'])) { |
| 137 | - throw new MapperException(strval($core['user_email']) . " is not a valid email address"); | |
| 186 | + throw new MapperException(sprintf(__("%s is not a valid email address", 'jc-importer'), strval($core['user_email']))); | |
| 138 | 187 | } |
| 139 | 188 | |
| 140 | 189 | Logger::debug('UserMapper::insert -wp_insert_user=' . wp_json_encode($core)); |
| 141 | 190 | |
| @@ -155,9 +204,8 @@ | ||
| 155 | 204 | if (!empty($meta)) { |
| 156 | 205 | foreach ($meta as $key => $value) { |
| 157 | 206 | if (!in_array($key, $this->_user_fields)) { |
| 158 | 207 | if (is_array($value)) { |
| 159 | - $this->clear_custom_field($this->ID, $key); | |
| 160 | 208 | foreach ($value as $v) { |
| 161 | 209 | $this->add_custom_field($this->ID, $key, $v); |
| 162 | 210 | } |
| 163 | 211 | } else { |
| @@ -167,8 +215,9 @@ | ||
| 167 | 215 | } |
| 168 | 216 | } |
| 169 | 217 | |
| 170 | 218 | $this->add_version_tag(); |
| 219 | + $this->add_reference_tag($data); | |
| 171 | 220 | $this->template->post_process($this->ID, $data); |
| 172 | 221 | |
| 173 | 222 | return $this->ID; |
| 174 | 223 | } |
| @@ -212,10 +261,10 @@ | ||
| 212 | 261 | // update user meta |
| 213 | 262 | if (!empty($meta)) { |
| 214 | 263 | foreach ($meta as $key => $value) { |
| 215 | 264 | if (!in_array($key, $this->_user_fields)) { |
| 265 | + $this->clear_custom_field($this->ID, $key); | |
| 216 | 266 | if (is_array($value)) { |
| 217 | - $this->clear_custom_field($this->ID, $key); | |
| 218 | 267 | foreach ($value as $v) { |
| 219 | 268 | $this->add_custom_field($this->ID, $key, $v); |
| 220 | 269 | } |
| 221 | 270 | } else { |
| @@ -225,8 +274,9 @@ | ||
| 225 | 274 | } |
| 226 | 275 | } |
| 227 | 276 | |
| 228 | 277 | $this->add_version_tag(); |
| 278 | + $this->add_reference_tag($data); | |
| 229 | 279 | $this->template->post_process($this->ID, $data); |
| 230 | 280 | |
| 231 | 281 | return $this->ID; |
| 232 | 282 | } |
| @@ -235,17 +285,30 @@ | ||
| 235 | 285 | { |
| 236 | 286 | if ($this->is_session_tag_enabled()) { |
| 237 | 287 | return $this->get_ids_without_session_tag('user'); |
| 238 | 288 | } else { |
| 289 | + | |
| 290 | + $import_ids = apply_filters('iwp/mapper/session_importer_ids', [$this->importer->getId()], $this->importer->getId()); | |
| 291 | + if (empty($import_ids)) { | |
| 292 | + return false; | |
| 293 | + } | |
| 294 | + | |
| 295 | + $meta_query = []; | |
| 296 | + foreach ($import_ids as $import_id) { | |
| 297 | + $meta_query[] = [ | |
| 298 | + 'key' => '_iwp_session_' . $import_id, | |
| 299 | + 'value' => $this->importer->getStatusId(), | |
| 300 | + 'compare' => '!=' | |
| 301 | + ]; | |
| 302 | + } | |
| 303 | + | |
| 304 | + if (count($meta_query) > 1) { | |
| 305 | + $meta_query['relation'] = 'AND'; | |
| 306 | + } | |
| 307 | + | |
| 239 | 308 | $wp_user_query = new \WP_User_Query([ |
| 240 | 309 | 'fields' => 'ID', |
| 241 | - 'meta_query' => array( | |
| 242 | - array( | |
| 243 | - 'key' => '_iwp_session_' . $this->importer->getId(), | |
| 244 | - 'value' => $this->importer->getStatusId(), | |
| 245 | - 'compare' => '!=' | |
| 246 | - ) | |
| 247 | - ), | |
| 310 | + 'meta_query' => $meta_query, | |
| 248 | 311 | 'number' => -1 |
| 249 | 312 | ]); |
| 250 | 313 | |
| 251 | 314 | $results = $wp_user_query->get_results(); |
| @@ -258,15 +321,19 @@ | ||
| 258 | 321 | } |
| 259 | 322 | |
| 260 | 323 | public function delete($id) |
| 261 | 324 | { |
| 262 | - require_once(ABSPATH . 'wp-admin/includes/user.php'); | |
| 263 | - wp_delete_user($id); | |
| 325 | + if (is_multisite()) { | |
| 326 | + remove_user_from_blog($id); | |
| 327 | + } else { | |
| 328 | + require_once(ABSPATH . 'wp-admin/includes/user.php'); | |
| 329 | + wp_delete_user($id); | |
| 330 | + } | |
| 264 | 331 | |
| 265 | 332 | $this->remove_session_tag($id, 'user'); |
| 266 | 333 | } |
| 267 | 334 | |
| 268 | - public function get_custom_field($id, $key, $single = true) | |
| 335 | + public function get_custom_field($id, $key = '', $single = false) | |
| 269 | 336 | { |
| 270 | 337 | return get_user_meta($id, $key, $single); |
| 271 | 338 | } |
| 272 | 339 | |
| @@ -295,9 +362,9 @@ | ||
| 295 | 362 | |
| 296 | 363 | add_user_meta($user_id, $key, $value); |
| 297 | 364 | } |
| 298 | 365 | |
| 299 | - public function update_custom_field($user_id, $key, $value) | |
| 366 | + public function update_custom_field($id, $key, $value, $unique = false, $skip_permissions = false) | |
| 300 | 367 | { |
| 301 | 368 | // Stop double serialization |
| 302 | 369 | if (is_serialized($value)) { |
| 303 | 370 | $value = unserialize($value); |
| @@ -302,9 +369,9 @@ | ||
| 302 | 369 | if (is_serialized($value)) { |
| 303 | 370 | $value = unserialize($value); |
| 304 | 371 | } |
| 305 | 372 | |
| 306 | - update_user_meta($user_id, $key, $value); | |
| 373 | + update_user_meta($id, $key, $value); | |
| 307 | 374 | } |
| 308 | 375 | |
| 309 | 376 | public function add_version_tag() |
| 310 | 377 | { |