How to create a logic hook based on info in subpanels

No forward movement…not an inch!

Even the very basic code is not working:

<?php

if (!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

class SUM
{
    function ENGScore($bean, $event, $arguments)
    {
        if($bean->target_type == "Leads" && $bean->related_type == "CampaignTrackers") 
        {           
               //$bean->log_sum_c = '505';  even this sample value is not entered in database
               $lead = BeanFactory::getBean('Lead', $bean->target_id);
               $lead->eng_sum_c = '55';
               $lead->save();
            }           
    }
}

I am just to surrender.

I don’t think that I have enough skills, or enough knowledge to create this high level logic hook.

With thanks,

RK

I think you are very close to getting this.

Do you know if the hook is executing? Were you able to set a breakpoint on the hook code?

If you were unsuccessful in setting a breakpoint, try inserting some logging code in the hook logic to see if it is executing.


file_put_contents("mylog.txt", "I made it here\r\n", FILE_APPEND);

Hit your url with the email link and see if mylog.txt shows up in the SuiteCRM root directory.

Dear mminnie,

I tried with this:

<?php

if (!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

class SUM
{
    function ENGScore($bean, $event, $arguments)
    {
        if($bean->target_type == "Leads" && $bean->related_type == "CampaignTrackers") 
        {           
               $bean->log_sum_c = '505';
               $lead = BeanFactory::getBean('Lead', $bean->target_id);
               $lead->eng_sum_c = '55';
               $lead->save();

               file_put_contents("mylog.txt", "Code executed!\r\n", FILE_APPEND);
            }     
    }
}

and clicked/browsed the url also .

No mylog.txt is created at the root folder of SuiteCRM.

With thanks,

RK

Put the file_put_contents as the first line of the ENGScore function.

And double check your logic_hooks line


$hook_array['after_save'][] = Array(1, 'Engagement Scoring via CampaignLogs', 'custom/modules/CampaignLogs/ENGScoring.php', 'SUM', 'ENGScore');

Did you put CampaignLogs (with an “S”) or CampaignLog??

it was ‘CampaignLog’
$hook_array[‘after_save’][] = Array(1, ‘Eng Scoring via CampaignLogs’, ‘custom/modules/CampaignLog/ENGScoring.php’, ‘SUM’, ‘ENGScore’);

I have just tried with logic_hooks.php:

<?php

$hook_version = 1; 
$hook_array = Array(); 
// position, file, function 
$hook_array['after_save'] = Array(); 
$hook_array['after_save'][] = Array(1, 'Eng Scoring via CampaignLogs', 'custom/modules/CampaignLog/ENGScoring.php', 'SUM', 'ENGScore');
?>

And ENGScoring.php as:

<?php

if (!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

class SUM
{
    function ENGScore($bean, $event, $arguments)
    {
        file_put_contents("mylog.txt", "Code executed!\r\n", FILE_APPEND);
        if($bean->target_type == "Leads" && $bean->related_type == "CampaignTrackers") 
        {           
               $bean->log_sum_c = '505';
               $lead = BeanFactory::getBean('Lead', $bean->target_id);
               $lead->eng_sum_c = '55';
               $lead->save();

               
            }     
    }
}

I again fired the url.

NO file has been created at the root of SuiteCRM.

RK

Dear mminnie, I can give you remote control via TeamViewer, if you want to have a look yourself.

I don’t think this forum has messaging. Find my Skype id in my profile and message me.

First…figure out if each time you use the same URL it creates a CampaignLog record or if you need to generate a new link in order to create a new CampaignLog record.

Skype me.

It does not create a new record. it only add (increment) the value of 1 to exist value of ‘hits’ (column) in MySQL table of ‘campaign_log’.

Just sent you the skype contact request.

Ok. The logic hook for CampaignLog doesn’t work in your case. This is because the Tracker URL link hits the entry point “campaign_trackerv2”.

The entry point is defined in include/MVC/Controller/entry_point_registry.php as:


    'campaign_trackerv2' => array('file' => 'modules/Campaigns/Tracker.php', 'auth' => false),

Looking at Tracker.php I see the “hits” field is incremented by using pure SQL and not a SuiteCRM Bean. Therefore the inherited Bean logic hook “after_save” will not be fired because the bean is not saving the record…the pure SQL is saving/updating the record.

So a logic hook will not work in this case.

You can intercept the incoming clicked link by creating a custom entry point named campaign_trackerv2. Notice the name is the same as the “stock” entry point. If you define this entry point in custom/application/Ext/EntryPointRegistry/entry_point_registry.ext.php, your entry point will override the stock entry point.

So first you need to add something like this to custom/application/Ext/EntryPointRegistry/entry_point_registry.ext.php:


$entry_point_registry['campaign_trackerv2'] = array('file' => 'custom/modules/CampaignLog/trackeroverride.php', 'auth' => false);

You can then create custom/modules/CampaignLog/trackeroverride.php to utilize the $_REQUEST[‘track’] value. Use this value to look up the tracker URL record to see if it is one that you want to have special processing.

You could either copy the Tracker.php code or you might want to use require_once(‘modules/Campaigns/Tracker.php’) at the end of your trackeroverride.php. Either way, you insert you checks/logic in trackeroverride.php.

So trackeroverride.php might look like:


require_once('modules/Campaigns/utils.php');

$GLOBALS['log'] = LoggerManager::getLogger('Campaign Tracker v2');

$db = DBManagerFactory::getInstance();

if(empty($_REQUEST['track'])) {
	$track = "";
} else {
	$track = $_REQUEST['track'];
}
if(!empty($_REQUEST['identifier'])) {
	$keys=log_campaign_activity($_REQUEST['identifier'],'link',true,$track);
    
}else{
    //if this has no identifier, then this is a web/banner campaign
    //pass in with id set to string 'BANNER'
    $keys=log_campaign_activity('BANNER','link',true,$track);

}

$track = $db->quote($track);

if(preg_match('/^[0-9A-Za-z\-]*$/', $track))
{
	$query = "SELECT tracker_url FROM campaign_trkrs WHERE id='$track'";
	$res = $db->query($query);

	$row = $db->fetchByAssoc($res);

        // ADDED CODE
        if ($row['tracker_url'] == 'http://suitecrm.com') {
           // Do special processing....including updating LEAD records
        }
	$redirect_URL = $row['tracker_url'];
	sugar_cleanup();
	header("Location: $redirect_URL");
}
else
{
	sugar_cleanup();
}
exit;
?>

Now your code is upgrade safe and the code should perform as before for all campaign trackers except for those that you code special logic.

1 Like

Hello mminnie,

What do I have gathered from your latest instruction is that:

And you want us not to think of building logic in terms of Beans, instead of MySQL queries.

Kindly have a look for , if I have understood it well.\

With thanks,

RK

Not quite. Take what you have in your screen shot (my pseudocode) but remove the require_once line you added. I should have not stated my thoughts about the require_once. I think it made it confusing.

Add your code to pull the lead bean and update. You might want to reference log_campaign_activity() function as a guide to get to the lead id. Then you can use BeanFactory::getBean(“Lead”, $leadid) to load the bean.

I would recommend to use BeanFactory::getBean() instead of direct SQL wherever possible. Some of the core PHP code in SuiteCRM uses SQL where it could have used a bean…but the better practice is to use a bean when possible.

Dear mminnie,

STEP -1 :

I had created a file named as ‘entry_point_registry.ext.php’ in ./custom/Extension/application/Ext/EntryPointRegistry/

The above file had the following content:

<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

$entry_point_registry['campaign_trackerv2'] = array('file' => 'custom/modules/Campaigns/trackeroverride.php', 'auth' => false);

?>

STEP -2 :
Then I went to ADMIN, and did Repair>Quick Repair and Rebuild, which automatically created a file named as ‘entry_point_registry.ext.php’ in a different folder path: ./custom/application/Ext/EntryPointRegistry/ (Reference: Custom Entry Points )

The content of this file were:

<?php 
 //WARNING: The contents of this file are auto-generated


if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');


$entry_point_registry['campaign_trackerv2'] = array('file' => 'custom/modules/Campaigns/trackeroverride.php', 'auth' => false);


?>

We can observe the //WARNING: The contents of this file are auto-generated, in this file.

Till this point everything is okay.

RK

Looks all good to me. Now you have to implement the code in trackeroverride.php.

Dear mminnie,

Next, I created a file named as ‘trackeroverride.php’ at location: ./custom/modules/Campaigns/

This file had the following contents:

<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

require_once('modules/Campaigns/utils.php');

$GLOBALS['log'] = LoggerManager::getLogger('Campaign Tracker v2');

$db = DBManagerFactory::getInstance();

if(empty($_REQUEST['track'])) {
	$track = "";
} else {
	$track = $_REQUEST['track'];
}
if(!empty($_REQUEST['identifier'])) {
	$keys=log_campaign_activity($_REQUEST['identifier'],'link',true,$track);
    
}else{
    //if this has no identifier, then this is a web/banner campaign
    //pass in with id set to string 'BANNER'
    $keys=log_campaign_activity('BANNER','link',true,$track);

}

$track = $db->quote($track);

if(preg_match('/^[0-9A-Za-z\-]*$/', $track))
{
	$query = "SELECT tracker_url FROM campaign_trkrs WHERE id='$track'";
	$res = $db->query($query);

	$row = $db->fetchByAssoc($res);

        // ADDED CODE
        if ($row['tracker_url'] == 'https://github.com/salesagility/SuiteCRM/pull/2454/commits/1a09fd2cffde60533c0fd03d1f33cfcc8e1e7105') 
        {
           // Do special processing....including updating LEAD records
			$query = " SELECT target_id, target_type FROM campaign_log";
			$res = $db->query($query);
			$row = $db->fetchByAssoc($res);
			$targetID = $row['target_id'];
			$targetType = $row['target_type'];
			if($targetType == 'Leads')
			{
			    $lead = BeanFactory::getBean('Lead', $targetID);
                $lead->eng_sum_c = '55';
                $lead->save();
            }
        
        }
	$redirect_URL = $row['tracker_url'];
	sugar_cleanup();
	header("Location: $redirect_URL");
}
else
{
	sugar_cleanup();
}

exit;
?>

I have tried to create a logic using some SQL queries. But I think that I am wrong.

Because nothing happens, when I access the tracked url from the browser.

php_error.log shows the following entries:

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP Notice:  Use of undefined constant target_type - assumed 'target_type' in C:\wamp64\www\luminisindia\SuiteCRM\custom\modules\Campaigns\trackeroverride.php on line 42

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP Stack trace:

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP   1. {main}() C:\wamp64\www\luminisindia\SuiteCRM\index.php:0

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP   2. SugarApplication->execute() C:\wamp64\www\luminisindia\SuiteCRM\index.php:54

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP   3. SugarController->execute() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\SugarApplication.php:105

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP   4. SugarController->process() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\Controller\SugarController.php:307

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP   5. SugarController->handleEntryPoint() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\Controller\SugarController.php:394

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP   6. require_once() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\Controller\SugarController.php:864

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP Notice:  Undefined index: tracker_url in C:\wamp64\www\luminisindia\SuiteCRM\custom\modules\Campaigns\trackeroverride.php on line 51

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP Stack trace:

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP   1. {main}() C:\wamp64\www\luminisindia\SuiteCRM\index.php:0

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP   2. SugarApplication->execute() C:\wamp64\www\luminisindia\SuiteCRM\index.php:54

[19-Jan-2017 19:59:21 Asia/Kolkata] PHP   3. SugarController->execute() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\SugarApplication.php:105

[19-Jan-2017 19:59:22 Asia/Kolkata] PHP   4. SugarController->process() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\Controller\SugarController.php:307

[19-Jan-2017 19:59:22 Asia/Kolkata] PHP   5. SugarController->handleEntryPoint() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\Controller\SugarController.php:394

[19-Jan-2017 19:59:22 Asia/Kolkata] PHP   6. require_once() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\Controller\SugarController.php:864

I request you to please help in correcting the code.

Soliciting your helping hand,

With thanks,

RK

Dear mminnie,

I made a minor correction at line 42 which is :

$targetType = $row['target_type'];

after that php_error log is throwing a notice at line 51;

[19-Jan-2017 20:31:36 Asia/Kolkata] PHP Notice:  Undefined index: tracker_url in C:\wamp64\www\luminisindia\SuiteCRM\custom\modules\Campaigns\trackeroverride.php on line 51

[19-Jan-2017 20:31:36 Asia/Kolkata] PHP Stack trace:

[19-Jan-2017 20:31:36 Asia/Kolkata] PHP   1. {main}() C:\wamp64\www\luminisindia\SuiteCRM\index.php:0

[19-Jan-2017 20:31:36 Asia/Kolkata] PHP   2. SugarApplication->execute() C:\wamp64\www\luminisindia\SuiteCRM\index.php:54

[19-Jan-2017 20:31:36 Asia/Kolkata] PHP   3. SugarController->execute() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\SugarApplication.php:105

[19-Jan-2017 20:31:36 Asia/Kolkata] PHP   4. SugarController->process() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\Controller\SugarController.php:307

[19-Jan-2017 20:31:36 Asia/Kolkata] PHP   5. SugarController->handleEntryPoint() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\Controller\SugarController.php:394

[19-Jan-2017 20:31:36 Asia/Kolkata] PHP   6. require_once() C:\wamp64\www\luminisindia\SuiteCRM\include\MVC\Controller\SugarController.php:864

where line 51 is having the code:

$redirect_URL = $row['tracker_url'];

With thanks,

RK

Simple…ask yourself…why does $row[‘tracker_url’] no longer exist??? Hmmm…maybe you reassigned $row? :smiley:

Dear mminnie,

There is 1-Lead & 1-Target (Prospects) in the TargetList which is being used to run this campaign.

The custom trackers worked and tracked url got redirected to the intended URL successfully.

But the value was not passed to field ‘eng_sum_c’.

Here is the code of trackeroverride.php currently:

<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

require_once('modules/Campaigns/utils.php');

$GLOBALS['log'] = LoggerManager::getLogger('Campaign Tracker v2');

$db = DBManagerFactory::getInstance();

if(empty($_REQUEST['track'])) {
	$track = "";
} else {
	$track = $_REQUEST['track'];
}
if(!empty($_REQUEST['identifier'])) {
	$keys=log_campaign_activity($_REQUEST['identifier'],'link',true,$track);
    
}else{
    //if this has no identifier, then this is a web/banner campaign
    //pass in with id set to string 'BANNER'
    $keys=log_campaign_activity('BANNER','link',true,$track);

}

$track = $db->quote($track);

if(preg_match('/^[0-9A-Za-z\-]*$/', $track))
{
	$query = "SELECT tracker_url FROM campaign_trkrs WHERE id='$track'";
	$res = $db->query($query);

	$row = $db->fetchByAssoc($res);

        // ADDED CODE
        if ($row['tracker_url'] == 'https://github.com/salesagility/SuiteCRM/pull/2454/commits/1a09fd2cffde60533c0fd03d1f33cfcc8e1e7105') 
        {
           // Do special processing....including updating LEAD records
			$query = " SELECT target_id, target_type FROM campaign_log";
			$res = $db->query($query);
			$row2 = $db->fetchByAssoc($res);
			$targetID = $row2['target_id'];
			$targetType = $row2['target_type'];
			if($targetType == 'Leads')
			{
			    $lead = BeanFactory::getBean('Lead', $targetID);
                $lead->eng_sum_c = '55';
                $lead->save();
            }
        
        }
	$redirect_URL = $row['tracker_url'];
	sugar_cleanup();
	header("Location: $redirect_URL");
}
else
{
	sugar_cleanup();
}

exit;
?>

I have tried to mimic what you did using NetBeans, I could see the following:

What is not working here?
May be beans code or anything else. Please guide.

With thanks,

RK

I don’t think you can rely upon the $keys value holding the lead bean information as your code will be called for any tracker url clicked.

You are going to have to determine a good WHERE clause to add to your query. Think about how you could pull only the data need.


$query = " SELECT target_id, target_type FROM campaign_log";  <-- No WHERE clause to narrow search...think about how many records will be in campaign_log

If you can’t get a where clause to pull only 1 record from campaign_log, then you will have to loop through the records returned. In your current code you are only pulling the first record from the query results. It should be something similar to:


   while ($row2 = $db->fetchByAssoc($res)) {
   }

You will have to inspect each $row2 record to determine if you should take action.

Dear mminnie,

I have today observed the following in php_error.log:

PHP Fatal error: Call to undefined method stdClass::save() in C:\wamp64\www\luminisindia\SuiteCRM\custom\modules\Campaigns\trackeroverride.php on line 49

Line 49 is : $lead->save();

This is the reason probably that the value in variable eng_sum_c is not being stored.

What is the solution?

With thanks,

RK