/** * 合并重复的联系人 * @param Contact $contact 联系人对象 * @param bool $is_append 是否新增数据 * @return Contact|bool */ private function _merge_duplicate_contact(Contact $contact, &$is_append) { $formatted_name = Contact_Helper::name_to_formatted_name($contact->get_family_name(), $contact->get_given_name(), $contact->get_prefix(), $contact->get_middle_name(), $contact->get_suffix()); /* 1.联系人姓名相同,且有一个手机号码相同的,判断为同一个联系人, 自动进行合并处理,合并时需要判断好友关系、公司、部门、职位、生日、 昵称、头像这几个信息是否有冲突,如果没有冲突则可以合并两个联系人 */ if (!empty($formatted_name)) { $same_name_tel_tag = new Contact(); $same_name_tel_tag->set_user_id($contact->get_user_id())->set_formatted_name($formatted_name); $result = $this->contact_mapper->find_by_tags($same_name_tel_tag); if (!empty($result)) { //冲突检测 foreach ($result as $id) { if (!in_array($id, $this->changed_ids)) { $find_contact = $this->get($contact->get_user_id(), $id); } else { $find_contact = $this->find_by_id($contact->get_user_id(), $id); } if ($find_contact !== FALSE) { //比较、合并失败进行下一项比较,不退出 if ($this->compare_info($contact->get_tels(), $find_contact->get_tels()) or $this->compare_info($contact->get_emails(), $find_contact->get_emails()) or $this->compare_info($contact->get_ims(), $find_contact->get_ims()) or $this->compare_info($contact->get_urls(), $find_contact->get_urls())) { //比较电话、邮箱、IM、网址看是否有交集 if ($find_contact->merge($contact, $is_append)) { return $find_contact; } } elseif (!$contact->get_tels() and !$contact->get_emails() and !$contact->get_ims() and !$contact->get_urls()) { //3 所有信息完全相同的联系人,可以合并 $contact_array = $contact->to_array(); //去除联系人的ID、创建时间、修改时间、来源、分组、自定义字段,姓名只比较全名后比较是否完全相同 unset($contact_array['id'], $contact_array['created_at'], $contact_array['modified_at'], $contact_array['category'], $contact_array['source'], $contact_array['customs'], $contact_array['given_name'], $contact_array['family_name'], $contact_array['middle_name'], $contact_array['prefix'], $contact_array['suffix']); $find_contact_array = array_intersect_key($find_contact->to_array(), $contact_array); list($new_md5, $curr_md5) = Photo_Controller::getoriginmd5(array($contact_array['avatar'], $find_contact_array['avatar'])); if (empty($contact_array['avatar']) or $contact_array['avatar'] == $find_contact_array['avatar'] or $new_md5 == $curr_md5) { unset($contact_array['avatar'], $find_contact_array['avatar']); if ($contact_array == $find_contact_array) { return $find_contact; } } } } } } } //2 两个联系人中有Email、IM、电话号码相同,其中一个没有姓名,在其他信息没有冲突情况下,可以合并 $tels = $contact->get_tels(); $emails = $contact->get_emails(); $ims = $contact->get_ims(); if (!empty($tels) or !empty($emails) or !empty($ims)) { $ids = array(); if (!empty($tels)) { $ids = array_merge($ids, $this->contact_mapper->get_id_by_info($contact->get_user_id(), 'tels', $tels)); } if (empty($ids) and !empty($emails)) { $ids = array_merge($ids, $this->contact_mapper->get_id_by_info($contact->get_user_id(), 'emails', $emails)); } if (empty($ids) and !empty($ims)) { $ids = array_merge($ids, $this->contact_mapper->get_id_by_info($contact->get_user_id(), 'ims', $ims)); } foreach ($ids as $id) { $find_contact = $this->get($contact->get_user_id(), $id); if ($find_contact !== FALSE and $find_contact->merge($contact, $is_append)) { return $find_contact; } } } //空名字,主要信息为空,存在信息完全相同的联系人不处理 /* if (empty($formatted_name)) { $same_name_tel_tag = new Contact(); $same_name_tel_tag->set_user_id($contact->get_user_id())->set_formatted_name( $formatted_name ); $result = $this->contact_mapper->find_by_tags( $same_name_tel_tag, empty($formatted_name) ? TRUE : FALSE ); if (! empty($result)) { //冲突检测 foreach ($result as $id) { $find_contact = $this->get($contact->get_user_id(), $id); if ($find_contact !== FALSE) { //3 所有信息完全相同的联系人,可以合并 $contact_array = $contact->to_array(); //去除联系人的ID、创建时间、修改时间后比较是否完全相同 unset($contact_array['id'], $contact_array['created_at'], $contact_array['modified_at'], $contact_array['health']); $find_contact_array = array_intersect_assoc( $find_contact->to_array(), $contact_array ); list ($new_md5, $curr_md5) = Photo_Controller::getoriginmd5( array( $contact_array['avatar'], $find_contact_array['avatar'] ) ); if (empty($contact_array['avatar']) or $contact_array['avatar'] == $find_contact_array['avatar'] or $new_md5 == $curr_md5 ) { unset($contact_array['avatar'], $find_contact_array['avatar']); if ($contact_array == $find_contact_array) { return $find_contact; } } } } } } */ return FALSE; }
/** * 合并联系人 * @param Contact $contact 联系人对象 * @param bool $is_append 是否新增 * @return bool 是否成功 */ public function merge(Contact $contact, &$is_append) { $curr_array = $this->to_array(); $new_array = $contact->to_array(); $check_arr = array('formatted_name', 'organization', 'department', 'title', 'birthday', 'nickname', 'avatar'); foreach ($check_arr as $key) { $curr = $curr_array[$key]; $new = $new_array[$key]; if ($key == 'avatar') { do { //其中一个头像为空或相同不冲突 if (empty($curr) or empty($new) or $curr == $new) { break; } //其中一个是默认头像 if (strrpos($new, Kohana::config('contact.avatar')) !== FALSE or strrpos($curr, Kohana::config('contact.avatar')) !== FALSE) { break; } list($new_md5, $curr_md5) = Photo_Controller::getoriginmd5(array($new, $curr)); if ($curr_md5 != $new_md5) { return FALSE; } } while (FALSE); } elseif ($key == 'birthday') { /* //忽略年份是1900 if (substr($curr, 0, 4) == 1900 or substr($new, 0, 4) == 1900 ) { $curr = substr($curr, 4); $new = substr($new, 4); } */ if (!empty($curr) and !empty($new) and $curr != $new) { return FALSE; } } else { if (!empty($curr) and !empty($new) and $curr != $new) { return FALSE; } } } foreach (self::$allowed_fields as $field) { $curr = $curr_array[$field]; $new = $new_array[$field]; $setter = 'set_' . $field; switch ($field) { case 'id': case 'source': case 'user_id': //不比较 break; case 'tels': if (!empty($new)) { $tmp = array(); foreach ($curr as $val) { $md5 = !empty($val['search']) ? md5(strtolower($val['type']) . $val['search']) : md5(strtolower($val['type']) . $val['value']); $tmp[] = $md5; } foreach ($new as $val) { $md5 = !empty($val['search']) ? md5(strtolower($val['type']) . $val['search']) : md5(strtolower($val['type']) . $val['value']); if ($val['value'] and !in_array($md5, $tmp)) { $is_append = TRUE; $curr[] = $val; $tmp[] = $md5; } } call_user_func(array($this, $setter), $curr); } break; case 'emails': case 'urls': case 'ims': case 'events': case 'relations': case 'customs': if (!empty($new)) { $tmp = array(); foreach ($curr as $val) { $tmp[] = md5(strtolower($val['type']) . $val['value']); } foreach ($new as $val) { $md5 = md5(strtolower($val['type']) . $val['value']); if ($val['value'] and !in_array($md5, $tmp)) { $is_append = TRUE; $curr[] = $val; $tmp[] = $md5; } } call_user_func(array($this, $setter), $curr); } break; case 'ims': if (!empty($new)) { $tmp = array(); foreach ($curr as $val) { $tmp[] = md5(strtolower($val['protocol']) . strtolower($val['type']) . $val['value']); } foreach ($new as $val) { $md5 = md5(strtolower($val['protocol']) . strtolower($val['type']) . $val['value']); if ($val['protocol'] and $val['value'] and !in_array($md5, $tmp)) { $is_append = TRUE; $curr[] = $val; $tmp[] = $md5; } } call_user_func(array($this, $setter), $curr); } break; case 'addresses': if (!empty($new)) { $tmp = array(); foreach ($curr as $val) { $tmp[] = md5(strtolower($val['type']) . $val['country'] . $val['region'] . $val['city'] . $val['street'] . $val['postal']); } foreach ($new as $val) { $md5 = md5(strtolower($val['type']) . $val['country'] . $val['region'] . $val['city'] . $val['street'] . $val['postal']); if (!in_array($md5, $tmp)) { $is_append = TRUE; $curr[] = $val; $tmp[] = $md5; } } call_user_func(array($this, $setter), $curr); } break; case 'avatar': if (empty($curr) or strrpos($curr, Kohana::config('contact.avatar')) !== FALSE) { if (!empty($new) and $curr != $new) { $is_append = TRUE; call_user_func(array($this, $setter), $new); } } break; case 'note': if ($curr == $new) { continue; } elseif (!empty($new) and !in_array($new, explode(' ', $curr))) { $is_append = TRUE; call_user_func(array($this, $setter), $curr . ' ' . $new); } break; case 'category': $curr_tmp = array_unique(array_filter(explode(',', $curr))); $new_tmp = array_unique(array_filter(explode(',', $new))); if (!empty($new_tmp) and array_diff($new_tmp, $curr_tmp)) { $is_append = TRUE; call_user_func(array($this, $setter), implode(',', array_unique(array_merge($curr_tmp, $new_tmp)))); } break; case 'prefix': case 'suffix': case 'given_name': case 'middle_name': case 'family_name': $formatted_name = $curr_array['formatted_name']; if (empty($formatted_name)) { $is_append = TRUE; call_user_func(array($this, $setter), $new); } break; default: if (empty($curr) and !empty($new)) { $is_append = TRUE; call_user_func(array($this, $setter), $new); } break; } } return TRUE; }