0

What I would like to achieve is to output some dynamic text coming from DB filled with unpredictable number of placeholders to be filled with some query parameters.

Basically it is an automation/notification system whereby upon user or admin's interaction with the website, some automation tasks will get triggered and added to DB. My closest shot at almost handling it is by using twig |replace filter in connection with twig extension. The problem is that I get to see the replaced text with the raw data not their parsed value. I guess it's better to look at my code. Your help is greatly appreciated.

DB Schema 'AutomationMsgTemplate, aka: amt'

raw_msg(text type) | format_keys(text type) | format_values(text type)
You are %USERNAME%  |      USERNAME         |         row.user.username
%No% %ORD_STATS% created |    NO, ORD_STATUS |        row.notif.x, row.order.y

My Service 'MsgFormatHelper' (facilitating twig ext)

public function renderMsgUsingSprintFormat(AutomationMsgTemplate $amt, GeneratedAutomationTask $gat): array
{
    $formatter_keys = $amt->getFormatKeys();
    $formatter_values = $amt->getFormatValues();

    $formatter_keys_arr = explode(",", $formatter_keys);
    $formatter_values_arr = explode(",", $formatter_values);

    $formatter_ready = array_combine($formatter_keys_arr, $formatter_values_arr);

    return $formatter_ready;
}

Twig extension

    class AppExtension extends AbstractExtension implements ServiceSubscriberInterface
{

private $container;
public function __construct(ContainerInterface $container)
{
    $this->container = $container;
}

public function getFunctions(): array
{
    return [
        new TwigFunction('msgSprint', [$this, 'renderMsg'])
    ];
}
 
public function renderMsg($amt, $gat): array
{
    return $this->container
        ->get(MsgFormatHelper::class)
        ->renderMsgUsingSprintFormat($amt, $gat);
}

public static function getSubscribedServices(): array
{
    return [
        MsgFormatHelper::class
    ];
}

}

And finally inside the twig

{% for i, row in incompleteTasks %}
    {% for amt in row.aet.automationMsgTemplates %}
        // MOMENT OF TRUTH IS BELOW:
       {% set format_arr = msgSprint(amt, row) %}
       {% set processedMsg = amt.message|replace(format_arr) %}
       {{ processedMsg }}

//nope, output is like: You are row.user.username
//sure enough below, as a debug test, works as intended
  {# {% set processedMsg = temp.message|replace({'%USERNAME%': row.ats.studentCourse.student.username}) %} #}

    {% endfor %}
 {% endfor %}
Ali
  • 216
  • 2
  • 11
  • You are not processing the values in `$formatter_values_arr`, you will need to either write a "parser" (in php) which evaluate the statements or render those with [`twig_template_from_string`](https://stackoverflow.com/a/30641564/446594) – DarkBee Jan 05 '22 at 15:15
  • Thanks @DarkBee, I am now able to parse the messages injected with proper values using the PHP eval() function and using the above service class inside a controller. Not a clean solution though, 3 nested foreach loops! So, I am still looking for a more elegant approach. About twig_template_from_string, not sure how to fit it into my code. – Ali Jan 05 '22 at 20:41
  • Could you update the code with the eval in it? Then maybe I could modify it for you – DarkBee Jan 06 '22 at 06:45

0 Answers0