// TODO: Extract all of this to a class for clarity and
// organization's sake.
- // sleep for a half second in order to avoid a race condition preventing badge creation.
- // This is somewhat sketchy, as this will tie up an apache processes, allowing for a DoS by someone
- // creating many phony memberships in a short period of time.
- // In practice, this isn't so bad. apache is currently configured to use prefork mpm on crmserver1p
- // and has about 40 forked processes. so 800 new memberships all at once would tie up the server for
- // an additional 10 seconds.
- usleep(500000);
-
// Get the oldest join date for the contact's memberships.
- $contactId = $objectRef->contact_id;
- $dao = CRM_Core_DAO::executeQuery(
- 'SELECT join_date FROM civicrm_membership WHERE contact_id=%1 ORDER BY join_date ASC LIMIT 1',
- array( 1 => array($contactId, 'Integer') )
- );
+ $getDao = function () {
+
+ $contactId = $objectRef->contact_id;
+ $dao = CRM_Core_DAO::executeQuery(
+ 'SELECT join_date FROM civicrm_membership WHERE contact_id=%1 ORDER BY join_date ASC LIMIT 1',
+ array( 1 => array($contactId, 'Integer') )
+ );
+ return $dao;
+ };
+
+ $dao = $getDao();
+ $fetchResult = $dao->fetch();
+
+ if(!$fetchResult) {
+ // retry after sleeping 2 seconds in order to avoid a race condition
+ usleep(2000000);
+ $dao->free();
+
+ $dao = $getDao();
+ $fetchResult = $dao->fetch();
+ }
- if($dao->fetch()) {
+ if($fetchResult) {
// Make the API call.
$joinDate = $dao->join_date;
$apiUrl = civicrm_api3('setting', 'getvalue', array(