How to create a logic hook based on info in subpanels

Dear mminnie,

I also attempted with inclusion of

(Line - 45) if($targetType == ā€˜Leadsā€™)
(Line - 46) {
(Line - 47) require_once(ā€˜modules/Leads/Lead.phpā€™); // I attempted this inclusion
(Line - 48) $lead = BeanFactory::getBean(ā€˜Leadā€™, $targetID);
(Line - 49) $lead->eng_sum_c = ā€˜55ā€™;
(Line - 50) $lead->save();
(Line - 51) }

Even now the php_errorlog shows the following:

[22-Jan-2017 16:15:07 Asia/Kolkata] PHP Warning:  Creating default object from empty value in C:\wamp64\www\luminisindia\SuiteCRM\custom\modules\Campaigns\trackeroverride.php on line 49

[22-Jan-2017 16:15:07 Asia/Kolkata] PHP Stack trace:

[22-Jan-2017 16:15:07 Asia/Kolkata] PHP   1. {main}() C:\wamp64\www\luminisindia\SuiteCRM\index.php:0

[22-Jan-2017 16:15:07 Asia/Kolkata] PHP   2. SugarApplication->execute() C:\wamp64\www\luminisindia\SuiteCRM\index.php:54

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

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

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

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

[22-Jan-2017 16:15:07 Asia/Kolkata] PHP Fatal error:  Call to undefined method stdClass::save() in C:\wamp64\www\luminisindia\SuiteCRM\custom\modules\Campaigns\trackeroverride.php on line 50

[22-Jan-2017 16:15:07 Asia/Kolkata] PHP Stack trace:

[22-Jan-2017 16:15:07 Asia/Kolkata] PHP   1. {main}() C:\wamp64\www\luminisindia\SuiteCRM\index.php:0

[22-Jan-2017 16:15:07 Asia/Kolkata] PHP   2. SugarApplication->execute() C:\wamp64\www\luminisindia\SuiteCRM\index.php:54

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

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

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

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

Can you guide further?

With thanks,

RK

You donā€™t have to add the require_once. The Lead.php will be loaded when you use BeanFactory.

Inspect the $beanList global variable.


// This is for inspection in your code....you don't need it to make your code work!
global $beanList;
var_dump($beanList);

Youā€™ll see that youā€™ll want to use the name of the moduleā€¦the plural Leads. The first parameter in getBeans is the module name. This may be different than the bean name. The module names can be also referenced by the name of the directories under the ā€œmodulesā€ SuiteCRM root.


BeanFactory::getBean("Leads", $targetId);

Dear mminnie,

Thanks for your latest input.

You were kind enough to elaborate that it is the name of ā€˜moduleā€™ which needs to be called in BeanFactory::getBean(ā€œLeadsā€, $targetID); command. I only needed to correct the Lead to ā€˜Leadsā€™.

IT WORKEDā€¦ and the input value got stored in the desired variable ā€˜eng_sum_cā€™ of Leads module.

What enhancement of code you would suggest for the situation, as there would be n-number of Leads clicking the same URL. Will it work for all of those click-throughs ?

And also there would be more URLs to click for them. Can I re-juggle the code so as to end with last IF-condition pointing to the URL in question?

With thanks,

RK

I havenā€™t worked with Campaigns and CampaignLogs, but I believe each link/lead combination will get a unique record in CampaignLog. If this is correct, the code should work as-is for different leads clicking on the same link.

I donā€™t fully understand your last question. Why wouldnā€™t your existing code point to the correct URL for each click?


	$redirect_URL = $row['tracker_url'];
	sugar_cleanup();
	header("Location: $redirect_URL");

Have you tested multiple leads and multiple URLs? If it doesnā€™t work, please explain with examples what is not working as desired.

Dear mminnie,

You are absolutely correct that when campaign Marketing is generated and send emails at scheduled time is clicked, it generates unique identifiers for each recipients. May be it takes care of tracked URL too with that identifier!

By my second question, what I meant was thatā€“

Whether I will have to repeat the following code-section n-number of times, as in real life we would be sending many emails with many URLs:

$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') 
        if ($row['tracker_url'] == 'http://support.sugarcrm.com/Knowledge_Base/Campaigns_Target_Lists/Creating_a_Campaign/index.html') 
        {
           // 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'];
			file_put_contents("mylogfile.log", "Code executed! and Track is ".$track. ".  Target_id is ".$targetID." and Target Type is:     ".$targetType."\r\n", FILE_APPEND);	
			if($targetType == 'Leads')
			{			    
			    // This is for inspection in your code....you don't need it to make your code work! - Mark Minnie
				//global $beanList;
				//var_dump($beanList);
				//I tested above code, but didn't see anything on screen - RK
			    $lead = BeanFactory::getBean('Leads', $targetID);
                $lead->eng_sum_c = '5050';
                $lead->save();                
            }        
        }
	$redirect_URL = $row['tracker_url'];
	sugar_cleanup();
	header("Location: $redirect_URL");
}
else
{
	sugar_cleanup();
}

or we can simply re-juggle the code in such a way that IF-condition which points to URL gets at the lower side of logic:

//if ($row['tracker_url'] == 'https://github.com/salesagility/SuiteCRM/pull/2454/commits/1a09fd2cffde60533c0fd03d1f33cfcc8e1e7105') 
        if ($row['tracker_url'] == 'http://support.sugarcrm.com/Knowledge_Base/Campaigns_Target_Lists/Creating_a_Campaign/index.html') 

so that we could create n-number of ELSE-IF scenarios for multiple URL and each scoring varying scores.

Something similar to the line of following code which I have used in a logic hook file:

if($bean->estimated_monthlysalary_c == "")
            $bean->fit_sum_c = $bean->fit_sum_c + '0';
        elseif($bean->estimated_monthlysalary_c == "100to499")
            $bean->fit_sum_c = $bean->fit_sum_c + '8';
        elseif($bean->estimated_monthlysalary_c == "500to999")
            $bean->fit_sum_c = $bean->fit_sum_c + '10';
        elseif($bean->estimated_monthlysalary_c == "1000to1499")
            $bean->fit_sum_c = $bean->fit_sum_c + '15';
        elseif($bean->estimated_monthlysalary_c == "1500to2499")
            $bean->fit_sum_c = $bean->fit_sum_c + '15';
        elseif($bean->estimated_monthlysalary_c == "2500to3999")
            $bean->fit_sum_c = $bean->fit_sum_c + '12';
        elseif($bean->estimated_monthlysalary_c == "4000_more")
            $bean->fit_sum_c = $bean->fit_sum_c + '10';

With the success of your code, I am thinking of how to scale or finding optimum way of scaling it.

With thanks,

RK

I donā€™t knowā€¦or have the vision of what you would be doing with each unique URL. Are you just inserting something different into the eng_sum_c field? Or would you be performing more complicated logic on the lead bean and maybe other beans based on the tracker url? Up to you to decide. That should guide you in determining what needs to be designed.

I would have you think about whether or not you can identify what similar logic you want performed on each tracker_url and then add a custom field to the Trackers module to identify the logic to perform. That way you could define a Tracker and set the logic to be performed by a user configurable setting.

Example code snip could be:


$trackerbean = BeanFactory::getBean("Trackers", $track);  // Use bean so any custom fields get loaded.  Creating custom fields in Studio creates field in different table...making query more complex.

if ($trackerbean->some_custom_field == "sumeng") {
     // Add field sum_eng_c
} else {
   // Do something else
}

Or the if could be a switch($trackerbean->some_custom_field).

This is if the logic is not too complex.

It also might be better for you to encapsulate the logic by extending the Tracker bean. This is a whole other learning curve, but could make the code more robust, easy to read, and extensible.

This is where the design comes inā€¦you might just try to make it work for now and refactor and rethink the logic when your needs arise in the future. Up to you.

Good luckā€¦and congratulations on getting it working!!!

Dear mminnie,

I am sorry for not making last message clear to the extent that the code snippet $lead->eng_sum_c = ā€˜5050ā€™; would get converted to:

$lead->eng_sum_c = eng_sum_c + ā€˜5050ā€™;

Initial value of this is ā€˜blankā€™.

It is wished to increment it : with each successive click of (new url)

For example

if URL A is clicked, then increment is of say 10
if URL B is clicked, then increment is of say 5
if URL C is clicked, then increment is of say 20
if URL D is clicked, then increment is of say 15

If he has clicked on A, B. C, D the eng_sum_c would be hold the value of 10+5+20+15 = 50

If he has clicked on A, C, D the eng_sum_c would be hold the value of 10+20+15 =45

RK

Dear mminnie,

I render my deeply felt gratitude to you for walking such a long length with me and literally bailing me out of very difficult spots.

With thanks,

RK

Not a problem. I like helping sometimes.

In the cases above you listed, I think it is definitely a case to have a custom field in the Trackers module. You would add a custom numeric field of click_value. If you add this in Studioā€¦remember it will be changed to click_value_c. Thenā€¦in your code you could just get the Tracker bean and add the value to eng_sum_c.

A question arises. What if the same user clicks on A, B, C, Dā€¦then a second time A? Do you want to add the value of A again?

Dear mminnie,

Good Day!

You asked ā€œA question arises. What if the same user clicks on A, B, C, Dā€¦then a second time A? Do you want to add the value of A again?ā€

You are right - we donā€™t want to add the value of A again.

:slight_smile:

I found a blog post about Getting a set of beans by conditions without SQL and was trying to work out the last piece of solution by following the example there.

You can observe what I was attempting in SAMPLE CODE section as shown in the graphic:

but the line 51 is throwing a php-error, which I am not able to solve.

PHP Parse error:  syntax error, unexpected ')' in C:\wamp64\www\luminisindia\SuiteCRM\custom\modules\Campaigns\trackeroverride.php on line 51

I request you to please help me in correcting this section of code.

With thanks,

RK


$CampaignLogRecords = $campaignLog->get_full_list('', "activity_type = 'link'");

Removed extra comma (,). You only need one = sign in the parameter. This will be a MySQL where and NOT a PHP evaluation.

1 Like

Thank you mminnie and the theachiever. Your posting helped me a lot.

I was in a similar situation. I wanted to create an Explicit Opt-In handler, whenever someone clicked on a link they are opted to my email. I could achieve so with the help of customized campaign tracker.

I also tried to generalize the handler so that it would would work with a token hint in the URL. Example, if my redirect URL is http://www.google.com and I would like to update an optin field on my target/lead/contact record whenever the link is clicked, I can drop a hint in my tracking URL such as

http://[optin]www.google.com (actually the [optin] could be anywhere in the redirect url).I have coded appropriate handling in the campaign log tracker. Refer the code for more details

=== trackeroverride.php ===

<?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); $identity = $_REQUEST['identifier']; }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, tracker_name FROM campaign_trkrs WHERE id='$track'"; $res = $db->query($query); $row = $db->fetchByAssoc($res); $redirect_URL = $row['tracker_url']; // Processing for [optin] token in the URL $token = "[optin]"; $pos = strpos( $row['tracker_url'], $token); if ($pos !== false) { // Do special processing....including updating LEAD records $query = " SELECT target_id, target_type FROM campaign_log where target_tracker_key ='$identity' limit 1" ; $res = $db->query($query); $row2 = $db->fetchByAssoc($res); $targetID = $row2['target_id']; $targetType = $row2['target_type']; if($targetType == 'Contacts') { $contact = BeanFactory::getBean('Contacts', $targetID); $contact->explicitoptin_c = 'true'; $contact->save(); } if($targetType == 'Leads') { $lead = BeanFactory::getBean('Leads', $targetID); $lead->explicitoptin_c = 'true'; $lead->save(); } if($targetType == 'Prospects') { $prospect = BeanFactory::getBean('Prospects', $targetID); $prospect->explicitoptin_c = 'true'; $prospect->save(); } //Reconstruct URL without token $redirect_URL = substr($row['tracker_url'] ,0,$pos ) . substr($row['tracker_url'], $pos - strlen($row['tracker_url'])+ strlen($token)); } sugar_cleanup(); //echo $redirect_URL; header("Location: $redirect_URL"); } else { sugar_cleanup(); } ?>

Glad I could be of some help.