"Defined by token" does not work for derived actions with ":" within plugin ID
>>> [!note] Migrated issue
<!-- Drupal.org comment -->
<!-- Migrated from issue #3536016. -->
Reported by: [starlight-sparkle](https://www.drupal.org/user/3804225)
>>>
<h3 id="summary-problem-motivation">Problem/Motivation</h3>
<p>When I try to use "Defined by token" option for the "Format" configuration in the "Render: Serialize" action, it always defaults to "json" when the action is executed.</p>
<p>Debugging reveals that this is because when the token named "eca_render_serialize:serialization_format" is retrieved, it actually retrieves a <code>\Drupal\Core\TypedData\Plugin\DataType\StringData</code> object instead of a scalar string. Hence when the action calls <code>getTokenValue()</code>:</p>
<div class="codeblock">
<pre><span style="color: #000000"><span style="color: #0000BB"><?php<br> </span><span style="color: #007700">protected function </span><span style="color: #0000BB">getTokenValue</span><span style="color: #007700">(</span><span style="color: #0000BB">string $fieldKey</span><span style="color: #007700">, </span><span style="color: #0000BB">string $default</span><span style="color: #007700">): </span><span style="color: #0000BB">string </span><span style="color: #007700">{<br> </span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">tokenService</span><span style="color: #007700">-></span><span style="color: #0000BB">getTokenData</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">buildTokenName</span><span style="color: #007700">(</span><span style="color: #0000BB">$fieldKey</span><span style="color: #007700">));<br> if (</span><span style="color: #0000BB">$value </span><span style="color: #007700">instanceof </span><span style="color: #0000BB">DataTransferObject</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">$value</span><span style="color: #007700">-></span><span style="color: #0000BB">getValue</span><span style="color: #007700">();<br> }<br> </span><span style="color: #FF8000">// StringData is not scalar, and it is not instance of DataTransferObject, so $default is returned.<br> </span><span style="color: #007700">return </span><span style="color: #0000BB">is_scalar</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">) ? (string) </span><span style="color: #0000BB">$value </span><span style="color: #007700">: </span><span style="color: #0000BB">$default</span><span style="color: #007700">;<br> }<br></span><span style="color: #0000BB">?></span></span></pre></div>
<p>Similar issues are observed for other actions such as "Render: Unserialize".</p>
<h4 id="summary-steps-reproduce">Steps to reproduce</h4>
<ol>
<li>Use Drupal 10.5.1</li>
<li>Enable ECA render, ECA base, and core serialization module</li>
<li>Create a model</li>
<ol>
<li>ECA custom event (Event ID: <code>test_token</code>)</li>
<li>Token: set value (Name: <code>eca_render_serialize:serialization_format</code> Value: <code>xml</code>)</li>
<li>Render: Serialize (Format: <code>Defined by token</code> Token name: <code>serialized</code> Value: <code>test: "yes"</code> Interpret as YAML: <code>Yes</code>)</li>
<li>Display a message to the user (Message: <code>[serialized]</code>)</li>
</ol>
<li>Run terminal command <code>drush eca:trigger:custom_event test_token</code></li>
<li>Observe that JSON output is printed instead of XML</li>
</ol>
<h3 id="summary-proposed-resolution">Proposed resolution</h3>
<p>Add an additional check for <code>TypedDataInterface</code> in <code>getTokenValue()</code> and if so, try to call <code>getValue()</code> on the object.</p>
<div class="codeblock">
<pre><span style="color: #000000"><span style="color: #0000BB"><?php<br> </span><span style="color: #007700">protected function </span><span style="color: #0000BB">getTokenValue</span><span style="color: #007700">(</span><span style="color: #0000BB">string $fieldKey</span><span style="color: #007700">, </span><span style="color: #0000BB">string $default</span><span style="color: #007700">): </span><span style="color: #0000BB">string </span><span style="color: #007700">{<br> </span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">tokenService</span><span style="color: #007700">-></span><span style="color: #0000BB">getTokenData</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">buildTokenName</span><span style="color: #007700">(</span><span style="color: #0000BB">$fieldKey</span><span style="color: #007700">));<br> if (</span><span style="color: #0000BB">$value </span><span style="color: #007700">instanceof </span><span style="color: #0000BB">DataTransferObject</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">$value</span><span style="color: #007700">-></span><span style="color: #0000BB">getValue</span><span style="color: #007700">();<br> }<br> if (</span><span style="color: #0000BB">$value </span><span style="color: #007700">instanceof </span><span style="color: #0000BB">TypedDataInterface</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">$value</span><span style="color: #007700">-></span><span style="color: #0000BB">getValue</span><span style="color: #007700">();<br> }<br> return </span><span style="color: #0000BB">is_scalar</span><span style="color: #007700">(</span><span style="color: #0000BB">$value</span><span style="color: #007700">) ? (string) </span><span style="color: #0000BB">$value </span><span style="color: #007700">: </span><span style="color: #0000BB">$default</span><span style="color: #007700">;<br> }<br></span><span style="color: #0000BB">?></span></span></pre></div>
<h3 id="summary-remaining-tasks">Remaining tasks</h3>
<h3 id="summary-ui-changes">User interface changes</h3>
<p>No changes</p>
<h3 id="summary-api-changes">API changes</h3>
<p>No changes</p>
<h3 id="summary-data-model-changes">Data model changes</h3>
issue