DEV Community

Dimitrios Desyllas
Dimitrios Desyllas

Posted on

Using An object method as a callable to update GDPR consent in DB

During development I has a case, where via a Mailing List api in order to retrieve the deleted subscribers from it.


// Making an Adapter (using GoF adapter pattern)
class MailingListApiAdapter
{
   const USUBBED_SUBSCRIBERS='....';
   const DELETED_SUBSCRIBERS='....';
   // Some Implementation here

   public function retrieveUnsubbedUsers(int $page=1,int &$total_pages): array
   {
      return $this->retrieveSubscribers(USUBBED_SUBSCRIBERS,$page,$total_pages);
   }


   public function retrieveDeletedUsers(int $page=1,int &$total_pages): array
   {
      return $this->retrieveSubscribers(DELETED_SUBSCRIBERS,$page,$total_pages);
   }

   private function retrieveSubscribers(string $url,int $page=1,int &$total_pages):array
   {
     // call api and return array
   }
}

Enter fullscreen mode Exit fullscreen mode

And due to a misconfig I had the stored consent of a user not on par with the mailing list. Therefore, I wanted to scan the existing lists and update the consent into the DB.

The consents is into the following RDBS table (I know it is not a specific db I try to keep db agnostic) :

user_consent
----
int user_id
string email
string consent_type
bool given_consent
Enter fullscreen mode Exit fullscreen mode

And I did the following script to update the consent:


function scan_list_and_update_consent(\PDO $dbh, Callable $retreiveSubscribersFunction){

   $dbh
   $page=1;
   $total_pages = 1;
      $sql = "UPDATE user_consent SET given_consent=false where consent_type='MAILING_LIST' and given_consent=true and email = :email";   
     $stmt = $dbh->prepare($sql);
   do {
     $dbh->beginTransaction();
     try{
       $subs = $retreiveSubscribersFunction($page,$limit);
       foreach($subs as $email){
          $stmt->execute(['email'=>$email]);  
       }
       $dbh->commit();
     } catch(\Exception $e){
       $dbh->rollback();
     }
     $page++;
     // We slow down the request frequency in order to avoid throttling
     sleep(3); 
   }while($page<=$total_pages);

}
Enter fullscreen mode Exit fullscreen mode

As you can see we iterate all pages (The second param is passed by reference at both retrieveUnsubbedUsersand retrieveDeletedUsers so we can retrieve the total pages with a singlwe request)

Also we assume that both both retrieveUnsubbedUsersand retrieveDeletedUsers return an array with emails:

[
  'user@example.com',
   ....
]
Enter fullscreen mode Exit fullscreen mode

So having a known logic we can call the function scan_list_and_update_consent like this:

function scan_list_and_update_consent(\PDO $dbh, Callable $retreiveSubscribersFunction){

   $dbh
   $page=1;
   $total_pages = 1;
      $sql = "UPDATE user_consent SET given_consent=false where consent_type='MAILING_LIST' and given_consent=true and email = :email";   
     $stmt = $dbh->prepare($sql);
   do {
     $dbh->beginTransaction();
     try{
       $subs = $retreiveSubscribersFunction($page,$limit);
       foreach($subs as $email){
          $stmt->execute(['email'=>$email]);  
       }
       $dbh->commit();
     } catch(\Exception $e){
       $dbh->rollback();
     }
     $page++;
     // We slow down the request frequency in order to avoid throttling
     sleep(3); 
   }while($page<=$total_pages);

}

$pdo = new PDO();
// Config pdo futher here

$mailingList = new MailingListApiAdapter();

// call $mailinglist->retrieveDeletedUsers
scan_list_and_update_consent($pdo,[$mailingList,'retrieveDeletedUsers']);


// call $mailinglist->retrieveUnsubbedUsers
scan_list_and_update_consent($pdo,[$mailingList,'retrieveUnsubbedUsers']);
Enter fullscreen mode Exit fullscreen mode

So as a result we can use functions with same signature (aka same parameter number and types) with a single piece of code avoiding duplicate code.

In our case we can add another function (eg. getNonReceivingEmailSubscribers) with same parameters ($page and $total_pages) and still be able to use it with scan_list_and_update_consent:

// call $mailinglist->retrieveUnsubbedUsers
scan_list_and_update_consent($pdo,[$mailingList,'getNonReceivingEmailSubscribers']);
Enter fullscreen mode Exit fullscreen mode

And we do not need to re-write the loop and the logic for fetching all pages for api calls.

Top comments (0)