Is it possible to alter the mailing form? I want to set the default value for url_tracking to false. Usually I would write a hook_civicrm_buildForm and set a custom default value but this hook is not being called when loading the mailing form.
6 Answers
Disclaimer: I'm not an angularjs expert
Again this is a bit of a hack, we are intercepting a built-in CiviCRM angular directive and extending to add behaviour.
Create a custom extensions or use an existing one and implement hook_civicrm_angularModules:
function myextension_civicrm_angularModules(&$angularModules){
$angularModules['myModule'] = array(
'ext' => 'myextension',
'js' => array('js/myModule.js'),
);
}
In your js file:
// js/myModule.js
(function(angular, $, _){
// Your module
angular.module('myModule', []);
// the hack
angular.module('crmMailing').config(function($provide){
// crmMailingBlockTracking directive
$provide.decorator('crmMailingBlockTrackingDirective', function($delegate){
var directive = $delegate[0];
// Original link function
var link = directive.link;
// compile function, returns new link function
directive.compile = function(){
return function(scope, element, attrs){
// get old link functionality
link.apply(this, arguments);
// new functionality here
scope.$parent.$watch(attrs.crmMailing, function(){
var createdDate = new Date(scope.mailing.created_date).getTime()/1000;
var nowDate = new Date().getTime()/1000;
if((nowDate - createdDate) < 60){
scope.mailing.url_tracking = '0';
CRM.alert('Tracking Disabled');
}
});
};
};
return $delegate;
});
});
})(angular, CRM.$, CRM._);
The angular Mailing app uses a kind of boilerplate service, crmMailingSimpleDirective
for constructing directives see here more info
The above snippet will do the same as my other answer without relying on setTimeout()
.
Hope that helps.
-
That's great, thank you! Folks can also set "Track Opens" to no by default, by using scope.mailing.open_tracking = '0'; instead of or in addition to scope.mailing.url_tracking = '0'; in the js file.– NorrisCommented Aug 10, 2017 at 0:27
I guess this is not the best way to do it and perhaps someone can point you to a better solution. I'll put it as an answer for readability purposes.
Edit
Create a custom extensions or use an exiting and implement hook_civicrm_pageRun
, something like:
function myextension_civicrm_pageRun(&$page){
$pageName = $page->getVar('_name');
if ($pageName == 'Civi\Angular\Page\Main') {
CRM_Core_Resources::singleton()->addScriptFile('myextension', 'js/myJsScript.js');
}
}
Edit: making some assumption this is with what I came up, as I said not the best thing to do but... perhaps someone finds it useful.
// js/myJsScript.js
CRM.$(function($){
var disableUrlTracking = function(){
// Access angular $scope
var mailingElement = document.querySelector('[ng-model="mailing.url_tracking"]');
var mailingScope = angular.element(mailingElement).scope();
// Convert the mailing created date into seconds
var createdDate = new Date(mailingScope.mailing.created_date).getTime()/1000;
// Current date into seconds
var nowDate = new Date().getTime()/1000;
// Compare both dates
var dif = nowDate - createdDate;
// if the difference is less 60 seconds, assuming that to creat a mailing takes more than 60 seconds
if(dif <= 60){
mailingScope.mailing.url_tracking = '0';
CRM.alert('URL Tracking disabled', 'URL Tracking');
}
}
// Optional: wait for the page to load completeley, in my case it takes some seconds until it renders the whole mailing page.
// If you don't have that issue just call the function
setTimeout(disableUrlTracking, 4000 );
});
-
But if the user enables url_tracking and saves the mailing as draft to finish it later, your code will disable it, when the user opens the page again. Commented Jan 26, 2016 at 8:03
-
Totally true, I haven't thought about that, my fault, I misunderstood your comment.– AndreiCommented Jan 26, 2016 at 8:09
-
Updated the answer, maybe you can find a better way to check if the mailing has been saved as a draft– AndreiCommented Jan 26, 2016 at 15:01
-
sorry that I've not accepted your answer. I'm still hoping that there might be an easy way to alter the form. Commented Apr 27, 2016 at 13:15
-
No worries, I agree there must be a better way to do it, at least it should, perhaps the
angular way
, but better doesn't necessarily mean easier, have a look at the Api explorer and try aget
action on the Mailing entity, the only way I see you could differentiate a saved draft from a new mailing is comparing thecreated_date
with the current date that is being edited, as there's no other property that I can think of that you could check for, for a sent/scheduled mailing you can see that you do have new properties like,is_completed, scheduled_date, scheduled_id, etc
– AndreiCommented Apr 28, 2016 at 0:01
In Drupal you can do this with hook_civicrm_pre():
function mymodule_civicrm_pre($op, $objectName, $id, &$params) {
if ($objectName == 'Mailing' && $op == 'create') {
$params['url_tracking'] = 0;
}
}
-
It seems this is the only answer that works with Mosaico. In Mosaico the email message is immediately saved before you can get to the Tracking tab. So, the angular/javascript based solutions are not executed until you click on the Tracking tab. But if you remember to click on the tracking tab, you don't really need this functionality. So, better turn it off on creation, and leave open the possibility of turning it back on when updated.– JamieCommented Sep 28, 2021 at 19:08
Another option you may want to consider is installing CiviProxy. You set it up somewhere on the public Internet (I imagine a free hosting account would suffice), whitelist its IP in your firewall, and it has a very limited ability to talk to CiviCRM. But the CiviProxy extension will rewrite your URL tracking to go to the proxy - and the proxy knows how to handle the rewrite. It also lets you, e.g. embed images in your mailing, which otherwise wouldn't be possible.
I wrote an extension borrowing heavily from @andrei, with a few improvements on identifying a creation vs modification of a draft
Hope you find it useful
/path/to/civi/civicrm/civicrm/ang/crmMailing/BlockTracking.html
addingng-init="mailing.url_tracking='0'"
to the url_tracking input, that will make the checkbox unchecked when the page loads, please note that this is not recommended, you will lose any changes made to those files when upgrading CiviCRM.