Variable Substitution - Project Variables Not Working

I submitted the following Bug to Dolibarr ERP & CRM on GitHub.

I just wanted to share this issue here to bring awareness.

Variable Substitution - Project Variables Not Working

Bug

The following variables do not work in email templates.

__PROJECT_ID__
__PROJECT_REF__
__PROJECT_NAME__

Environment Version

13.0.1

Environment OS

Ubuntu 18.04.5 LTS

Environment Web server

Apache/2.4.29 (Ubuntu)

Environment PHP

PHP 7.2.24

Environment Database

MariaDB

Environment URL(s)

/admin/mails_templates.php

Expected and actual behavior

The following Variable Substitutions are not populating the Project Emails as expected:

__PROJECT_ID__
__PROJECT_REF__
__PROJECT_NAME__

When using any of the above variables, the email message body just prints their key.
Example of variable in an email message:
image

The expected behavior would be:
Print out the Project id for __PROJECT_ID__
Print out the Project ref for __PROJECT_REF__
Print out the Project title for __PROJECT_NAME__

I am pretty confident that the following lines in htdocs/core/lib/functions.lib.php never get hit:

if (is_object($object->project))
{
	$substitutionarray['__PROJECT_ID__'] = (is_object($object->project) ? $object->project->id : '');
	$substitutionarray['__PROJECT_REF__'] = (is_object($object->project) ? $object->project->ref : '');
	$substitutionarray['__PROJECT_NAME__'] = (is_object($object->project) ? $object->project->title : '');
}
if (is_object($object->projet))	// Deprecated, for backward compatibility
{
	$substitutionarray['__PROJECT_ID__'] = (is_object($object->projet) ? $object->projet->id : '');
	$substitutionarray['__PROJECT_REF__'] = (is_object($object->projet) ? $object->projet->ref : '');
	$substitutionarray['__PROJECT_NAME__'] = (is_object($object->projet) ? $object->projet->title : '');
}

I will note that even though the following code does not exist in htdocs/core/lib/functions.lib.php, it will print out the expected values in Project emails when they are added outside of the conditional blocks for if (is_object($object->project)) and if (is_object($object->projet)):

$substitutionarray['__PROJECT_ID__'] = $object->id;
$substitutionarray['__PROJECT_REF__'] = $object->ref;
$substitutionarray['__PROJECT_NAME__'] = $object->title;

Steps to reproduce the behavior

Create a project email template with any of these variables:

__PROJECT_ID__
__PROJECT_REF__
__PROJECT_NAME__

Send a Project email using the email template.

Attached files

No response

I have a workaround until the Dolibarr Admirals come up with a patch to address the bug I found.

Following the documentation for Other personalized tags
I created a new file in htdocs/custom/emailnotifications/core/substitutions/ called functions_emailnotifications.lib.php
Inside the functions file, I created the following function called emailnotifications_completesubstitutionarray in my custom module called EmailNotifications.

/**         Function called to complete substitution array (before generating on ODT, or a personalized email)
 *      functions xxx_completesubstitutionarray are called by make_substitutions() if file
 *      is inside directory htdocs/core/substitutions
 * 
 *      @param  array       $substitutionarray  Array with substitution key=>val
 *      @param  Translate   $langs          Output langs
 *      @param  Object      $object         Object to use to get values
 *      @return void                    The entry parameter $substitutionarray is modified
 */
function emailnotifications_completesubstitutionarray(&$substitutionarray,$langs,$object)
{
   global $conf,$db,$object;

   $emailnotification_project_id = isset( $object ) && isset( $object->id ) && ! empty( $object->id ) ? $object->id : '';
   $emailnotification_project_ref = isset( $object ) && isset( $object->ref ) && ! empty( $object->ref ) ? $object->ref : '';
   $emailnotification_project_title = isset( $object ) && isset( $object->title ) && ! empty( $object->title ) ? $object->title : '';

   $emailnotifications_substitutionarray['__emailnotification_project_id__'] = $emailnotification_project_id;
   $emailnotifications_substitutionarray['__emailnotification_project_ref__'] = $emailnotification_project_ref;
   $emailnotifications_substitutionarray['__emailnotification_project_name__'] = $emailnotification_project_title;

   if (!is_object($outputlangs)) $outputlangs = $langs;
   $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, array(), $object);
   $substitutionarray = array_merge($substitutionarray, $emailnotifications_substitutionarray);
}

Then in htdocs/custom/emailnotifications/core/modules/modEmailNotifications.class.php I enabled substitutions:

$this->module_parts = array(
	// Set this to 1 if module has its own substitution function file (core/substitutions)
	'substitutions' => 1,
);

Now I can use the following custom Variable Substitutions in my email templates and print out the expected values in the Project emails I send:

__emailnotification_project_id__
__emailnotification_project_ref__
__emailnotification_project_name__

Here is an updated function: smaller and cleaner:

function emailnotifications_completesubstitutionarray(&$substitutionarray,$langs,$object)
{
   // If $object IS-A Project provide substitutions
   if (is_object($object) && get_class($object) === 'Project') {  

      $substitutionarray['__PROJECT_ID__'] = $object->id;
      $substitutionarray['__PROJECT_REF__'] = $object->ref;
      $substitutionarray['__PROJECT_NAME__'] = $object->title;
   }
}

I decided to stay with the original naming conventions, so that in the event that they get fixed, then we don’t have to go and update all the email templates to take on the fix.

Instad of

__emailnotification_project_id__
__emailnotification_project_ref__
__emailnotification_project_name__

I’m using

__PROJECT_ID__
__PROJECT_REF__
__PROJECT_NAME__
1 Like