Prevent logic hook from saving

I have a logic hook triggering before_relationship_add for the Accounts module.

This checks all contacts if certain flags are set and throws an error if not all the flags are found on the related contacts.

After throwing the error, it looks like the save was prevented, but as soon as I refresh, I can see that the change has been saved even though an error was thrown in the logic hook!

How do I prevent the save from happening?

Derick

Parents
  • This does not seem to be a problem when using a 'before_save' hook.

    I assume this gets triggered before the 'before_relationship_add' hook and by the time my hook is triggered, the save has already happened. This would explain the issue I was witnessing.

    Derick

  • Hi Derick van Niekerk

                Can you post the snippet of the code you have used in the 'before_relationship_add' hook.

    To my knowledge the $bean doesnt contain information regarding the records but the aruguments does

    Regards

    Sidhu

  • I am triggering this on 'before_relationship_delete' and 'before_relationship_add' on Contacts and 'before_save' on both Contacts and Accounts.

    It basically checks if all 5 communication flags are set across all contacts related to an account. If not, it should throw an error unless the update is done by a system script via the api.

    I'm not sure how much is relevant, but here it is:

        function check_valid_prefs($bean, $event, $arguments) {
            $relAccounts = [];
            $currentContactId = null;
            $isContact = ($bean->object_name == 'Contact');
            $isAccount = ($bean->object_name == 'Account');
            $isRelationshipHook = (strpos($event, 'relationship') !== false);
           
            if($isRelationshipHook) {
                if($isContact) {
                    $contactBean = clone $bean;
                }
                if($isAccount) { // We only need to trigger this logic once for a relationship
                    return true;
                }
            }

            if ($isContact) {
                if ($_SESSION['authenticated_user_id'] == '1') { // System user (not available in bean on 'before_save')
                    return true; // Do not do any checks if the system is creating the account (most likely Marketo)
                }
                $relAccounts = $bean->get_linked_beans('accounts', 'Account');
                //$accBean = new Account();
                //$accBean->retrieve($bean->account_id);
                //$relAccounts[] = $accBean;
                $currentContactId = $bean->id;
               
            } elseif ($isAccount) {
                $relAccounts[] = $bean;
            }
           
            // Check if this change affects any related accounts
            foreach ($relAccounts as $Account) {
                if ($Account->performance_opt_out_c == 1)
                    continue; // ignore the subscription logic if opted out

                $sem = $seo = $net = $prt = $srv = false;
               
                // This call overwrites the data in the current bean ( if this $bean is a Contact type)
                $relContacts = $Account->get_linked_beans('contacts', 'Contacts');
                foreach ($relContacts as $Contact) {
                   
                    if($isContact && $isRelationshipHook && $contactBean->id == $Contact->id) {
                        $Contact = $contactBean;
                    }
                   
                    if (count($relContacts) == 1) {
                        // If it's the only contact, set all preferences
                        $this->_setAllPreferenceForContact($Contact);
                    }

                    if ($Contact->id == $currentContactId
                            && $event == 'before_relationship_delete'
                            && count($relContacts) > 1) {       // unless it's the only contact left
                        continue;
                    }                   

                    if ($Contact->accounts_contacts_contact_status != 'Active')
                        continue; // Ignore this contact if it's not Active

                    $sem = $sem || $Contact->preference_sem_report_c == 1;
                    $seo = $seo || $Contact->preference_seo_report_c == 1;
                    $net = $net || $Contact->preference_network_report_c == 1;
                    $prt = $prt || $Contact->preference_print_rollovers_c == 1;
                    $srv = $srv || $Contact->preference_service_messages_c == 1;
                }
                // are any of the flags not set?
                if (!($sem && $seo && $net && $prt && $srv)
                        && (count($relContacts) > 0)
                        && $Account->na_account_status_c != 'verified_lead') {
                    $missing = array();
                    if (!$sem)
                        $missing[] = 'SEM Report';
                    if (!$seo)
                        $missing[] = 'SEO Report';
                    if (!$net)
                        $missing[] = 'Network Report';
                    if (!$prt)
                        $missing[] = 'Print Rollovers';
                    if (!$srv)
                        $missing[] = 'Service Messages';


                    $msg = "When trying to save '{$bean->object_name}' ($bean->id). "
                            . "These changes will cause account '{$Account->name}' ({$Account->id}) "
                            . "to have invalid preference centre settings. "
                            . "Please make sure there is at least one contact for each setting. "
                            . "The missing flags are: " . implode(', ', $missing);

                    throw new SugarApiExceptionInvalidParameter($msg);
                }
            }
        }

    This seems to work ok on the 'before_save' hooks, but on the 'before_relationship_add' hook, the error message triggers, but it saves anyway.

Reply
  • I am triggering this on 'before_relationship_delete' and 'before_relationship_add' on Contacts and 'before_save' on both Contacts and Accounts.

    It basically checks if all 5 communication flags are set across all contacts related to an account. If not, it should throw an error unless the update is done by a system script via the api.

    I'm not sure how much is relevant, but here it is:

        function check_valid_prefs($bean, $event, $arguments) {
            $relAccounts = [];
            $currentContactId = null;
            $isContact = ($bean->object_name == 'Contact');
            $isAccount = ($bean->object_name == 'Account');
            $isRelationshipHook = (strpos($event, 'relationship') !== false);
           
            if($isRelationshipHook) {
                if($isContact) {
                    $contactBean = clone $bean;
                }
                if($isAccount) { // We only need to trigger this logic once for a relationship
                    return true;
                }
            }

            if ($isContact) {
                if ($_SESSION['authenticated_user_id'] == '1') { // System user (not available in bean on 'before_save')
                    return true; // Do not do any checks if the system is creating the account (most likely Marketo)
                }
                $relAccounts = $bean->get_linked_beans('accounts', 'Account');
                //$accBean = new Account();
                //$accBean->retrieve($bean->account_id);
                //$relAccounts[] = $accBean;
                $currentContactId = $bean->id;
               
            } elseif ($isAccount) {
                $relAccounts[] = $bean;
            }
           
            // Check if this change affects any related accounts
            foreach ($relAccounts as $Account) {
                if ($Account->performance_opt_out_c == 1)
                    continue; // ignore the subscription logic if opted out

                $sem = $seo = $net = $prt = $srv = false;
               
                // This call overwrites the data in the current bean ( if this $bean is a Contact type)
                $relContacts = $Account->get_linked_beans('contacts', 'Contacts');
                foreach ($relContacts as $Contact) {
                   
                    if($isContact && $isRelationshipHook && $contactBean->id == $Contact->id) {
                        $Contact = $contactBean;
                    }
                   
                    if (count($relContacts) == 1) {
                        // If it's the only contact, set all preferences
                        $this->_setAllPreferenceForContact($Contact);
                    }

                    if ($Contact->id == $currentContactId
                            && $event == 'before_relationship_delete'
                            && count($relContacts) > 1) {       // unless it's the only contact left
                        continue;
                    }                   

                    if ($Contact->accounts_contacts_contact_status != 'Active')
                        continue; // Ignore this contact if it's not Active

                    $sem = $sem || $Contact->preference_sem_report_c == 1;
                    $seo = $seo || $Contact->preference_seo_report_c == 1;
                    $net = $net || $Contact->preference_network_report_c == 1;
                    $prt = $prt || $Contact->preference_print_rollovers_c == 1;
                    $srv = $srv || $Contact->preference_service_messages_c == 1;
                }
                // are any of the flags not set?
                if (!($sem && $seo && $net && $prt && $srv)
                        && (count($relContacts) > 0)
                        && $Account->na_account_status_c != 'verified_lead') {
                    $missing = array();
                    if (!$sem)
                        $missing[] = 'SEM Report';
                    if (!$seo)
                        $missing[] = 'SEO Report';
                    if (!$net)
                        $missing[] = 'Network Report';
                    if (!$prt)
                        $missing[] = 'Print Rollovers';
                    if (!$srv)
                        $missing[] = 'Service Messages';


                    $msg = "When trying to save '{$bean->object_name}' ($bean->id). "
                            . "These changes will cause account '{$Account->name}' ({$Account->id}) "
                            . "to have invalid preference centre settings. "
                            . "Please make sure there is at least one contact for each setting. "
                            . "The missing flags are: " . implode(', ', $missing);

                    throw new SugarApiExceptionInvalidParameter($msg);
                }
            }
        }

    This seems to work ok on the 'before_save' hooks, but on the 'before_relationship_add' hook, the error message triggers, but it saves anyway.

Children