We are running an event with around 1000 users who have to submit something every day. When they submit, their email is stored in a list in an option in WordPress.
I have encountered a problem where two users have submitted an entry at the same time - the following function is called twice at the same time:
function tw_add_user_to_submitted_today_list($user_email){
$tw_settings = get_option("tw_settings");
if (!in_Array($user_email, $tw_settings['submitted_today'])){
array_push( $tw_settings['submitted_today'], $user_email);
update_option("tw_settings", $tw_settings);
}
}
One of the users is not being added to the list because the list is being overwritten before being resaved.
I'm stuck to think of a better or different way of doing this. Is there a way of checking if a process is already running for example?
In asynchronous requests, updating rows in the database (although very rare) creates the possibility of data loss. Instead of update, data can be stored by adding and deleting rows.
I recommend using update_metadata() and get_metadata().
// Adds an email address to the email list in the database.
// If the email address is already in the list, no action is taken.
function add_email_to_list_atakanau( $email ) {
$admin_user_id = 123; // ID of the (user) object metadata is for.
// Check if the email address exists.
if ( get_metadata( 'user', $admin_user_id, 'email_list', true ) ) {
$email_list = get_metadata( 'user', $admin_user_id, 'email_list' );
if ( in_array( $email, $email_list ) ) {
return;
}
}
// Add the email address to the list.
add_metadata( 'user', $admin_user_id, 'email_list', $email );
}
In this example, metadata has been added to the user profile. You can use your own user ID.
$admin_user_id = 123;
Or other data source:
$meta_type: Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', or any other object type with an associated meta table.
Each data value is stored in a new row in the database. So there is no overwriting problem:
meta_id | user_id | meta_key | meta_value |
---|---|---|---|
1000 | 123 | email_list | email1@domain.tld |
1001 | 123 | email_list | email2@domain.tld |
Also, for reading and deleting:
// Removes an email address from the email list in the database.
function remove_email_from_list_atakanau( $email ) {
delete_metadata( 'user', 123, 'email_list', $email );
}
// Gets the email list from the database.
function get_email_list_atakanau() {
return get_metadata( 'user', 123, 'email_list' );
}