Skip to content

Instantly share code, notes, and snippets.

@xnau
Last active March 28, 2023 04:10
Show Gist options
  • Save xnau/54c0fb799707ce9b3a56714e9f6ae517 to your computer and use it in GitHub Desktop.
Save xnau/54c0fb799707ce9b3a56714e9f6ae517 to your computer and use it in GitHub Desktop.
Demonstrates how to set up a multiple-field match when a signup form is submitted or importing a CSV to Participants Database
<?php
/*
* Plugin Name: PDb Multi-Field Match Import
* Description: Demonstrates how to set up a multiple-field match when a signup form is submitted or importing a CSV to Participants Database
* Version: 2.0
*
*/
class PDb_Multifield_Match_Import {
/**
* @var array list of fields to match on import
*
* set this array to the fields that must match between the incoming data
* and the database
*/
private $match_field_list = array( 'first_name', 'last_name' );
/**
* @var int this holds the ID of the matched record or int 0 if no match
*/
private $match_id = 0;
/**
* @var bool if true, only apply the multi-field match to CSV imports
*
* if false, this will also attempt to match records on a signup form submission
*
* by default, this plugin only looks at CSV imports for a match
*/
private $import_only = true;
/**
* sets up our filters
*/
public function __construct()
{
add_action( 'pdb-incoming_record_match_object', array( $this, 'check_for_match' ), 10, 3 );
add_filter( 'pdb-process_form_matched_record', array( $this, 'provide_the_matched_id' ) );
}
/**
* checks the incoming data against the database to find a match
*
* @param \PDb_submission\matching\record $match object
*/
public function check_for_match( $match )
{
if ( $this->skip_this_match( $match ) )
{
return;
}
// set the match_id property to the result of our search
$this->match_id = $this->check_db_for_match( $this->match_data( $match->post ) );
// return true if we have a match
$match->set_match_status( $this->match_id !== false );
}
/**
* checks to see if the incoming match should be skipped
*
* @param \PDb_submission\matching\import $match object
* @return bool true to skip matching the submission
*/
private function skip_this_match( $match )
{
if ( $this->import_only && ! $match->is_csv_import() )
{
return true;
}
// if the posted data doesn't have the match fields present, don't attempt a match
if ( count( array_intersect( array_keys( $match->post ), $this->match_field_list ) ) !== count( $this->match_field_list ) )
{
return true;
}
return false;
}
/**
* supplies the matched id
*
* @param int $match_id the matched id found by the standard method (we ignore this)
*
* @return int the matched record ID
*/
public function provide_the_matched_id( $match_id )
{
return $this->match_id;
}
/**
* queries the database with the match field data to find a match
*
* @global wpdb $wpdb
* @param array $match_data the data to use in finding the match as $name => $value
*
* @return int|bool the record ID if there is a match, bool false if no match
*/
private function check_db_for_match( $match_data )
{
$query = 'SELECT `id` FROM ' . Participants_Db::$participants_table . ' WHERE ' . $this->where_clause();
global $wpdb;
$result = $wpdb->get_col( $wpdb->prepare( $query, $match_data ) );
// add debugging to make sure the query and result is as expected
Participants_Db::debug_log(__METHOD__.' query: '.$wpdb->last_query.' result: '.print_r($result,1), 2);
// make sure there is only one match, then return the found ID
if ( count( $result ) === 1 ) {
return current( $result );
}
// no match or more than one match
return false;
}
/**
* provides the where clause
*
* @return string where clause forthe match query
*/
private function where_clause()
{
$where_clause = array();
// make an array of all the subclauses
foreach ( $this->match_field_list as $field ) {
$where_clause[] = '`' . $field . '` = "%s"';
}
// string them all together to build the clause
return implode( ' AND ', $where_clause);
}
/**
* provides the match data array
*
* this extracts the match field data from the posted data
*
* @param array $post the posted data
*
* @return array the extracted data
*/
private function match_data( $post )
{
$match_data = array();
foreach ( $this->match_field_list as $field ) {
$match_data[] = isset( $post[$field] ) ? $post[$field] : '';
}
return $match_data;
}
}
new PDb_Multifield_Match_Import;
@xnau
Copy link
Author

xnau commented Aug 18, 2020

Aug 18, 2020 Fixed an error with the argument count.

@rchavess
Copy link

Dear Ronald,
I need to prevent duplicate records at the sign-up form. Basically, in the sign-up form I have an ID field and I need to prevent duplicate IDs.
Can you please help to prevent duplicate records by validating one filed of the sign-up form?
Thank you in advance,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment