}
}
+ /**
+ * If a contact list is specified then adjust the query to ensure one contact is in that list.
+ *
+ * Doing an OR join here will lead to a server-killing unindexed query. However, a union will
+ * perform better.
+ *
+ * @param array $contactList
+ * @param string $query
+ * @param string $strID1
+ * @param string $strID2
+ *
+ * @return string
+ */
+ protected static function filterQueryByContactList(array $contactList, $query, $strID1 = 'contact1.id', $strID2 = 'contact2.id') {
+ if (empty($contactList)) {
+ return $query . " AND ($strID1 < $strID2)";
+ }
+ $contactIDs = implode(',', $contactList);
+ return "$query AND $strID1 IN ($contactIDs) AND $strID1 > $strID2
+ UNION $query AND $strID1 > $strID2 AND $strID2 IN ($contactIDs) AND $strID1 NOT IN ($contactIDs)
+ ";
+
+ }
+
}
* @return array
*/
public static function internal($rg) {
- $query = "
+ $query = self::filterQueryByContactList($rg->contactIds, "
SELECT contact1.id as id1, contact2.id as id2, {$rg->threshold} as weight
FROM civicrm_contact as contact1
JOIN civicrm_email as email1 ON email1.contact_id=contact1.id
JOIN civicrm_email as email2 ON
email2.contact_id=contact2.id AND
email1.email=email2.email
- WHERE contact1.contact_type = 'Individual'
- AND " . self::internalFilters($rg);
+ WHERE contact1.contact_type = 'Individual'");
+
return array(
"civicrm_contact.{$rg->name}.{$rg->threshold}" => $query,
);