<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://sugarclub.sugarai.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Declarative and Serializable Metadata</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata</link><description /><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>Declarative and Serializable Metadata</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata</link><pubDate>Mon, 02 Jun 2025 17:23:46 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:45d31bd2-8243-4a49-82c4-90ea10831c03</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata#comments</comments><description>Current Revision posted to Dev Tutorials by Rafael Fernandes on 6/2/2025 5:23:46 PM&lt;br /&gt;
&lt;p data-start="171" data-end="432"&gt;This guide is here to help developers follow best practices when working with Declarative and Serializable Metadata in Sugar. We&amp;#39;ve identified some common mistakes developers make and put together practical tips on how to avoid them using proven best practices.&lt;/p&gt;
&lt;h2 id="mcetoc_1isogltk43"&gt;General Guidelines for Declarative Metadata:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Static Definitions&lt;/strong&gt;: Always use static and explicit values rather than computed ones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid Direct Database&lt;/strong&gt; &lt;strong&gt;Calls&lt;/strong&gt;: Metadata should not perform direct database queries&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Avoid Using $GLOBALS Array&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;Metadata definitions should directly declare configurations explicitly instead of relying on global variables.&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$GLOBALS[&amp;quot;dictionary&amp;quot;][&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;: Use the local $dictionary variable directly:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$dictionary[&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;: Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Remove Entry Point Validations&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Entry point checks are unnecessary in metadata definitions, as these files should be simple data files..&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!defined(&amp;#39;sugarEntry&amp;#39;) || !sugarEntry) die(&amp;#39;Not A Valid Entry Point&amp;#39;);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt; Simply omit such checks from metadata entirely.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Avoid Conditional Class Checks and Dynamic Includes&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Don&amp;#39;t use conditional logic or dynamic includes in metadata definitions.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!class_exists(&amp;#39;VardefManager&amp;#39;)) {
    require_once &amp;#39;include/SugarObjects/VardefManager.php&amp;#39;;
}
VardefManager::createVardef(&amp;#39;MyModule&amp;#39;,&amp;#39;MyModule&amp;#39;, [&amp;#39;basic&amp;#39;,&amp;#39;assignable&amp;#39;]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt; Rely on autoloading and straightforward declarations&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;VardefManager::createVardef(&amp;#39;MyModule&amp;#39;,&amp;#39;MyModule&amp;#39;, [&amp;#39;basic&amp;#39;,&amp;#39;assignable&amp;#39;]);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&amp;nbsp;we plan to introduce a better way of extending vardefs from module templates. It will be more declarative and should avoid VardefManager::createVardef calls inside the vardefs files.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Logic hooks&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Separate definition from implementation where Metadata&amp;nbsp;declares where Logic Hook should be triggered from.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;gt; head -n8 custom/modules/logic_hooks.php

&amp;lt;?php
class InstallationReviewHistory
{
    static $already_ran = false;
    private $update_project_relations;
    public function createRecordFromX($bean, $event, $arguments)
    {&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;code&gt;custom/modules/logic_hooks.php&lt;/code&gt;&amp;nbsp;must&amp;nbsp;contain the Logic Hook definition and not the class itself&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
    $hook_version = 1;
    $hook_array = Array();
    $hook_array[&amp;#39;after_session_start&amp;#39;] = Array();
    $hook_array[&amp;#39;after_session_start&amp;#39;][] = Array(
        //Processing index. For sorting the array.
        1, 
        //Label. A string value to identify the hook.
        &amp;#39;after_session_start example&amp;#39;,
        //The PHP file where your class is located.
        &amp;#39;custom/modules/application_hooks_class.php&amp;#39;,
        //The class the method is in.
        &amp;#39;application_hooks_class&amp;#39;, 
        //The method to call.
        &amp;#39;after_session_start_method&amp;#39; 
    );&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Metadata files&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;(view defs, vardefs, etc) that are supposed to have specific&amp;nbsp;code defined as arrays should not have any function calls in them or any other logic like string concatenation or loops.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;foreach ([&amp;quot;after_retrieve&amp;quot;, &amp;quot;after_fetch_query&amp;quot;, &amp;quot;after_entry_point&amp;quot;, &amp;quot;CallsApiHelper_formatForApi_after&amp;quot;, &amp;quot;MeetingsApiHelper_formatForApi_after&amp;quot;] as $hkNameToInit) {
    ...
foreach ($aHooks as &amp;amp;$aHook) {
    ...
foreach ($hook_array as $sEvent =&amp;gt; &amp;amp;$aHooks) {&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Views/Layouts definitions&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Compiled definitions should only contain array definitions.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;: existing code in &lt;code&gt;custom/application/Ext/clients/base/layouts/header/header.ext.php&lt;/code&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$u2af72f100c356273d46284f6fd1dfc08 = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module1\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;quot;sugar_version&amp;quot;]);
---
$u2af72f100c356273d46284f6fd1dfc08 = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module2\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;quot;sugar_version&amp;quot;]);
---
$u2af72f100c356273d46284f6fd1dfc08 = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module1\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;quot;sugar_version&amp;quot;]);
---
$version = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module3\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;#39;sugar_version&amp;#39;]);
---
$version = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module2\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;#39;sugar_version&amp;#39;]);
---
$version = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module1\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;#39;sugar_version&amp;#39;]);
---
if (\SugarAutoloader::fileExists(&amp;#39;custom/src/MyCompany/Module3/Libraries/PHP/Classes/Sugar/Version.php&amp;#39;) &amp;amp;&amp;amp; class_exists(&amp;#39;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module3\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;#39;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;#39;sugar_version&amp;#39;])) {
---
if (\SugarAutoloader::fileExists(&amp;#39;custom/src/MyCompany/Module2/Libraries/PHP/Classes/Sugar/Version.php&amp;#39;) &amp;amp;&amp;amp; class_exists(&amp;#39;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module2\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;#39;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;#39;sugar_version&amp;#39;])) {
---
if (\SugarAutoloader::fileExists(&amp;#39;custom/src/MyCompany/Module1/Libraries/PHP/Classes/Sugar/Version.php&amp;#39;) &amp;amp;&amp;amp; class_exists(&amp;#39;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module1\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;#39;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;#39;sugar_version&amp;#39;])) {
---
if (\SugarAutoloader::fileExists(&amp;quot;custom/src/MyCompany/CallCenter/Libraries/PHP/Classes/Sugar/Version.php&amp;quot;) &amp;amp;&amp;amp; class_exists(&amp;quot;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\CallCenter\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;quot;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;quot;sugar_version&amp;quot;])) {
---
if (\SugarAutoloader::fileExists(&amp;quot;custom/src/MyCompany/Module2/Libraries/PHP/Classes/Sugar/Version.php&amp;quot;) &amp;amp;&amp;amp; class_exists(&amp;quot;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module2\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;quot;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;quot;sugar_version&amp;quot;])) {
&lt;/pre&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example 2&lt;/strong&gt;: existing code in&amp;nbsp;&lt;code&gt;custom/modules/Contacts/Ext/clients/base/views/record/record.ext.php&lt;/code&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;After Salesfusion Install&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Install Marker 1&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Install Marker 2&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Install Marker 3: &amp;#39;.$k);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Install Marker 4&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Install Marker 5&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Starting Extension code for Contacts.... &amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;quot;Implicit for Module1: Error - &amp;quot; . $e-&amp;gt;getMessage());
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;After My MLP Install&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 1&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 2&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 3: &amp;#39; . $k);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 3: &amp;#39;.$k);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 4&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 5&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Starting Extension code for Contacts.... &amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Starting Extension code for Contacts.... &amp;#39;); $module = &amp;#39;Contacts&amp;#39;; $addAdhocButton = array( &amp;#39;type&amp;#39; =&amp;gt; &amp;#39;rowaction&amp;#39;, &amp;#39;event&amp;#39; =&amp;gt; &amp;#39;button:my_adhoc:click&amp;#39;, &amp;#39;tooltip&amp;#39; =&amp;gt; &amp;#39;LBL_MY_ADHOC_MEET_TOOLTIP&amp;#39;, &amp;#39;css_class&amp;#39; =&amp;gt; &amp;#39;btn&amp;#39;, &amp;#39;showOn&amp;#39; =&amp;gt; &amp;#39;view&amp;#39;, &amp;#39;icon&amp;#39; =&amp;gt; &amp;#39;fa-comment&amp;#39;, ); $addCreateMeetingButton = array( &amp;#39;type&amp;#39; =&amp;gt; &amp;#39;rowaction&amp;#39;, &amp;#39;event&amp;#39; =&amp;gt; &amp;#39;button:my_create_meeting:click&amp;#39;, &amp;#39;tooltip&amp;#39; =&amp;gt; &amp;#39;LBL_MY_CREATE_MEET_TOOLTIP&amp;#39;, &amp;#39;css_class&amp;#39; =&amp;gt; &amp;#39;btn&amp;#39;, &amp;#39;showOn&amp;#39; =&amp;gt; &amp;#39;view&amp;#39;, &amp;#39;icon&amp;#39; =&amp;gt; &amp;#39;fa-calendar&amp;#39;, ); if (!isset($viewdefs[$module][&amp;#39;base&amp;#39;][&amp;#39;view&amp;#39;][&amp;#39;record&amp;#39;][&amp;#39;buttons&amp;#39;])) { $GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 1&amp;#39;); require_once(&amp;#39;clients/base/views/record/record.php&amp;#39;); $viewdefs[$module][&amp;#39;base&amp;#39;][&amp;#39;view&amp;#39;][&amp;#39;record&amp;#39;][&amp;#39;buttons&amp;#39;] = $viewdefs[&amp;#39;base&amp;#39;][&amp;#39;view&amp;#39;][&amp;#39;record&amp;#39;][&amp;#39;buttons&amp;#39;]; } array_unshift($viewdefs[$module][&amp;#39;base&amp;#39;][&amp;#39;view&amp;#39;][&amp;#39;record&amp;#39;][&amp;#39;buttons&amp;#39;],$addAdhocButton,$addCreateMeetingButton); $GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;After My_Component Install&amp;#39;);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;metadata definition only&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
$viewdefs[&amp;#39;base&amp;#39;][&amp;#39;layout&amp;#39;][&amp;#39;header&amp;#39;] = [
    &amp;#39;components&amp;#39; =&amp;gt; [
        [
            &amp;#39;layout&amp;#39; =&amp;gt; &amp;#39;module-list&amp;#39;,
        ],
        [
            &amp;#39;layout&amp;#39; =&amp;gt; &amp;#39;quicksearch&amp;#39;,
        ],
        [
            &amp;#39;view&amp;#39; =&amp;gt; &amp;#39;notifications&amp;#39;,
        ],
        [
            &amp;#39;view&amp;#39; =&amp;gt; &amp;#39;profileactions&amp;#39;,
        ],
        [
            &amp;#39;view&amp;#39; =&amp;gt; &amp;#39;quickcreate&amp;#39;,
        ],
    ],
    &amp;#39;last_state&amp;#39; =&amp;gt; [
        &amp;#39;id&amp;#39; =&amp;gt; &amp;#39;app-header&amp;#39;,
        &amp;#39;defaults&amp;#39; =&amp;gt; [
            &amp;#39;last-home&amp;#39; =&amp;gt; &amp;#39;dashboard&amp;#39;,
        ],
    ],
];&lt;/pre&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: Development Best Practices&lt;/div&gt;
</description></item><item><title>Declarative and Serializable Metadata</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata/revision/6</link><pubDate>Mon, 02 Jun 2025 14:49:14 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:45d31bd2-8243-4a49-82c4-90ea10831c03</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata#comments</comments><description>Revision 6 posted to Dev Tutorials by Rafael Fernandes on 6/2/2025 2:49:14 PM&lt;br /&gt;
&lt;p data-start="171" data-end="432"&gt;This guide is here to help developers follow best practices when working with Declarative and Serializable Metadata in Sugar. We&amp;#39;ve identified some common mistakes developers make and put together practical tips on how to avoid them using proven best practices.&lt;/p&gt;
&lt;h2 id="mcetoc_1isogltk43"&gt;General Guidelines for Declarative Metadata:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Static Definitions&lt;/strong&gt;: Always use static and explicit values rather than computed ones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid Direct Database&lt;/strong&gt; &lt;strong&gt;Calls&lt;/strong&gt;: Metadata should not perform direct database queries&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Avoid Using $GLOBALS Array&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;Metadata definitions should directly declare configurations explicitly instead of relying on global variables.&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$GLOBALS[&amp;quot;dictionary&amp;quot;][&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;: Use the local $dictionary variable directly:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$dictionary[&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;: Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Remove Entry Point Validations&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Entry point checks are unnecessary in metadata definitions, as these files should be simple data files..&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!defined(&amp;#39;sugarEntry&amp;#39;) || !sugarEntry) die(&amp;#39;Not A Valid Entry Point&amp;#39;);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt; Simply omit such checks from metadata entirely.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Avoid Conditional Class Checks and Dynamic Includes&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Don&amp;#39;t use conditional logic or dynamic includes in metadata definitions.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!class_exists(&amp;#39;VardefManager&amp;#39;)) {
    require_once &amp;#39;include/SugarObjects/VardefManager.php&amp;#39;;
}
VardefManager::createVardef(&amp;#39;MyModule&amp;#39;,&amp;#39;MyModule&amp;#39;, [&amp;#39;basic&amp;#39;,&amp;#39;assignable&amp;#39;]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt; Rely on autoloading and straightforward declarations&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;VardefManager::createVardef(&amp;#39;MyModule&amp;#39;,&amp;#39;MyModule&amp;#39;, [&amp;#39;basic&amp;#39;,&amp;#39;assignable&amp;#39;]);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&amp;nbsp;we plan to introduce a better way of extending vardefs from module templates. It will be more declarative and should avoid VardefManager::createVardef calls inside the vardefs files.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Logic hooks&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Separate definition from implementation where Metadata&amp;nbsp;declares where Logic Hook should be triggered from.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;gt; head -n8 custom/modules/logic_hooks.php

&amp;lt;?php
class InstallationReviewHistory
{
    static $already_ran = false;
    private $update_project_relations;
    public function createRecordFromX($bean, $event, $arguments)
    {&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;code&gt;custom/modules/logic_hooks.php&lt;/code&gt;&amp;nbsp;must&amp;nbsp;contain the Logic Hook definition and not the class itself&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
    $hook_version = 1;
    $hook_array = Array();
    $hook_array[&amp;#39;after_session_start&amp;#39;] = Array();
    $hook_array[&amp;#39;after_session_start&amp;#39;][] = Array(
        //Processing index. For sorting the array.
        1, 
        //Label. A string value to identify the hook.
        &amp;#39;after_session_start example&amp;#39;,
        //The PHP file where your class is located.
        &amp;#39;custom/modules/application_hooks_class.php&amp;#39;,
        //The class the method is in.
        &amp;#39;application_hooks_class&amp;#39;, 
        //The method to call.
        &amp;#39;after_session_start_method&amp;#39; 
    );&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Metadata files&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;(view defs, vardefs, etc) that are supposed to have specific&amp;nbsp;code defined as arrays should not have any function calls in them or any other logic like string concatenation or loops.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;foreach ([&amp;quot;after_retrieve&amp;quot;, &amp;quot;after_fetch_query&amp;quot;, &amp;quot;after_entry_point&amp;quot;, &amp;quot;CallsApiHelper_formatForApi_after&amp;quot;, &amp;quot;MeetingsApiHelper_formatForApi_after&amp;quot;] as $hkNameToInit) {
    ...
foreach ($aHooks as &amp;amp;$aHook) {
    ...
foreach ($hook_array as $sEvent =&amp;gt; &amp;amp;$aHooks) {&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Views/Layouts definitions&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Compiled definitions should only contain array definitions.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;: existing code in &lt;code&gt;custom/application/Ext/clients/base/layouts/header/header.ext.php&lt;/code&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$u2af72f100c356273d46284f6fd1dfc08 = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module1\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;quot;sugar_version&amp;quot;]);
---
$u2af72f100c356273d46284f6fd1dfc08 = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module2\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;quot;sugar_version&amp;quot;]);
---
$u2af72f100c356273d46284f6fd1dfc08 = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module1\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;quot;sugar_version&amp;quot;]);
---
$version = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module3\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;#39;sugar_version&amp;#39;]);
---
$version = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module2\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;#39;sugar_version&amp;#39;]);
---
$version = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module1\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;#39;sugar_version&amp;#39;]);
---
if (\SugarAutoloader::fileExists(&amp;#39;custom/src/MyCompany/Module3/Libraries/PHP/Classes/Sugar/Version.php&amp;#39;) &amp;amp;&amp;amp; class_exists(&amp;#39;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module3\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;#39;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;#39;sugar_version&amp;#39;])) {
---
if (\SugarAutoloader::fileExists(&amp;#39;custom/src/MyCompany/Module2/Libraries/PHP/Classes/Sugar/Version.php&amp;#39;) &amp;amp;&amp;amp; class_exists(&amp;#39;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module2\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;#39;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;#39;sugar_version&amp;#39;])) {
---
if (\SugarAutoloader::fileExists(&amp;#39;custom/src/MyCompany/Module1/Libraries/PHP/Classes/Sugar/Version.php&amp;#39;) &amp;amp;&amp;amp; class_exists(&amp;#39;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module1\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;#39;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;#39;sugar_version&amp;#39;])) {
---
if (\SugarAutoloader::fileExists(&amp;quot;custom/src/MyCompany/CallCenter/Libraries/PHP/Classes/Sugar/Version.php&amp;quot;) &amp;amp;&amp;amp; class_exists(&amp;quot;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\CallCenter\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;quot;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;quot;sugar_version&amp;quot;])) {
---
if (\SugarAutoloader::fileExists(&amp;quot;custom/src/MyCompany/Module2/Libraries/PHP/Classes/Sugar/Version.php&amp;quot;) &amp;amp;&amp;amp; class_exists(&amp;quot;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module2\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;quot;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;quot;sugar_version&amp;quot;])) {
&lt;/pre&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example 2&lt;/strong&gt;: existing code in&amp;nbsp;&lt;code&gt;custom/modules/Contacts/Ext/clients/base/views/record/record.ext.php&lt;/code&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;After Salesfusion Install&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Install Marker 1&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Install Marker 2&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Install Marker 3: &amp;#39;.$k);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Install Marker 4&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Install Marker 5&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;#39;Starting Extension code for Contacts.... &amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;fatal(&amp;quot;Implicit for Module1: Error - &amp;quot; . $e-&amp;gt;getMessage());
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;After My MLP Install&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 1&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 2&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 3: &amp;#39; . $k);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 3: &amp;#39;.$k);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 4&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 5&amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Starting Extension code for Contacts.... &amp;#39;);
---
$GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Starting Extension code for Contacts.... &amp;#39;); $module = &amp;#39;Contacts&amp;#39;; $addAdhocButton = array( &amp;#39;type&amp;#39; =&amp;gt; &amp;#39;rowaction&amp;#39;, &amp;#39;event&amp;#39; =&amp;gt; &amp;#39;button:my_adhoc:click&amp;#39;, &amp;#39;tooltip&amp;#39; =&amp;gt; &amp;#39;LBL_MY_ADHOC_MEET_TOOLTIP&amp;#39;, &amp;#39;css_class&amp;#39; =&amp;gt; &amp;#39;btn&amp;#39;, &amp;#39;showOn&amp;#39; =&amp;gt; &amp;#39;view&amp;#39;, &amp;#39;icon&amp;#39; =&amp;gt; &amp;#39;fa-comment&amp;#39;, ); $addCreateMeetingButton = array( &amp;#39;type&amp;#39; =&amp;gt; &amp;#39;rowaction&amp;#39;, &amp;#39;event&amp;#39; =&amp;gt; &amp;#39;button:my_create_meeting:click&amp;#39;, &amp;#39;tooltip&amp;#39; =&amp;gt; &amp;#39;LBL_MY_CREATE_MEET_TOOLTIP&amp;#39;, &amp;#39;css_class&amp;#39; =&amp;gt; &amp;#39;btn&amp;#39;, &amp;#39;showOn&amp;#39; =&amp;gt; &amp;#39;view&amp;#39;, &amp;#39;icon&amp;#39; =&amp;gt; &amp;#39;fa-calendar&amp;#39;, ); if (!isset($viewdefs[$module][&amp;#39;base&amp;#39;][&amp;#39;view&amp;#39;][&amp;#39;record&amp;#39;][&amp;#39;buttons&amp;#39;])) { $GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;Install Marker 1&amp;#39;); require_once(&amp;#39;clients/base/views/record/record.php&amp;#39;); $viewdefs[$module][&amp;#39;base&amp;#39;][&amp;#39;view&amp;#39;][&amp;#39;record&amp;#39;][&amp;#39;buttons&amp;#39;] = $viewdefs[&amp;#39;base&amp;#39;][&amp;#39;view&amp;#39;][&amp;#39;record&amp;#39;][&amp;#39;buttons&amp;#39;]; } array_unshift($viewdefs[$module][&amp;#39;base&amp;#39;][&amp;#39;view&amp;#39;][&amp;#39;record&amp;#39;][&amp;#39;buttons&amp;#39;],$addAdhocButton,$addCreateMeetingButton); $GLOBALS[&amp;#39;log&amp;#39;]-&amp;gt;info(&amp;#39;After My_Component Install&amp;#39;);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;metadata definition only&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$viewdefs[&amp;#39;base&amp;#39;][&amp;#39;layout&amp;#39;][&amp;#39;header&amp;#39;] = [
    &amp;#39;components&amp;#39; =&amp;gt; [
        [
            &amp;#39;layout&amp;#39; =&amp;gt; &amp;#39;module-list&amp;#39;,
        ],
        [
            &amp;#39;layout&amp;#39; =&amp;gt; &amp;#39;quicksearch&amp;#39;,
        ],
        [
            &amp;#39;view&amp;#39; =&amp;gt; &amp;#39;notifications&amp;#39;,
        ],
        [
            &amp;#39;view&amp;#39; =&amp;gt; &amp;#39;profileactions&amp;#39;,
        ],
        [
            &amp;#39;view&amp;#39; =&amp;gt; &amp;#39;quickcreate&amp;#39;,
        ],
    ],
    &amp;#39;last_state&amp;#39; =&amp;gt; [
        &amp;#39;id&amp;#39; =&amp;gt; &amp;#39;app-header&amp;#39;,
        &amp;#39;defaults&amp;#39; =&amp;gt; [
            &amp;#39;last-home&amp;#39; =&amp;gt; &amp;#39;dashboard&amp;#39;,
        ],
    ],
];&lt;/pre&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: Development Best Practices&lt;/div&gt;
</description></item><item><title>Declarative and Serializable Metadata</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata/revision/5</link><pubDate>Mon, 02 Jun 2025 14:38:48 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:45d31bd2-8243-4a49-82c4-90ea10831c03</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata#comments</comments><description>Revision 5 posted to Dev Tutorials by Rafael Fernandes on 6/2/2025 2:38:48 PM&lt;br /&gt;
&lt;p data-start="171" data-end="432"&gt;This guide is here to help developers follow best practices when working with Declarative and Serializable Metadata in Sugar. We&amp;#39;ve identified some common mistakes developers make and put together practical tips on how to avoid them using proven best practices.&lt;/p&gt;
&lt;h2 id="mcetoc_1isogltk43"&gt;General Guidelines for Declarative Metadata:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Static Definitions&lt;/strong&gt;: Always use static and explicit values rather than computed ones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avoid Direct Database&lt;/strong&gt; &lt;strong&gt;Calls&lt;/strong&gt;: Metadata should not perform direct database queries&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Avoid Using $GLOBALS Array&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;Metadata definitions should directly declare configurations explicitly instead of relying on global variables.&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$GLOBALS[&amp;quot;dictionary&amp;quot;][&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;: Use the local $dictionary variable directly:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$dictionary[&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;: Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Remove Entry Point Validations&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Entry point checks are unnecessary in metadata definitions, as these files should be simple data files..&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!defined(&amp;#39;sugarEntry&amp;#39;) || !sugarEntry) die(&amp;#39;Not A Valid Entry Point&amp;#39;);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt; Simply omit such checks from metadata entirely.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Avoid Conditional Class Checks and Dynamic Includes&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Don&amp;#39;t use conditional logic or dynamic includes in metadata definitions.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!class_exists(&amp;#39;VardefManager&amp;#39;)) {
    require_once &amp;#39;include/SugarObjects/VardefManager.php&amp;#39;;
}
VardefManager::createVardef(&amp;#39;MyModule&amp;#39;,&amp;#39;MyModule&amp;#39;, [&amp;#39;basic&amp;#39;,&amp;#39;assignable&amp;#39;]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt; Rely on autoloading and straightforward declarations&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;VardefManager::createVardef(&amp;#39;MyModule&amp;#39;,&amp;#39;MyModule&amp;#39;, [&amp;#39;basic&amp;#39;,&amp;#39;assignable&amp;#39;]);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&amp;nbsp;we plan to introduce a better way of extending vardefs from module templates. It will be more declarative and should avoid VardefManager::createVardef calls inside the vardefs files.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Logic hooks&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Separate definition from implementation where Metadata&amp;nbsp;declares where Logic Hook should be triggered from.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;gt; head -n8 custom/modules/logic_hooks.php

&amp;lt;?php
class InstallationReviewHistory
{
    static $already_ran = false;
    private $update_project_relations;
    public function createRecordFromX($bean, $event, $arguments)
    {&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;code&gt;custom/modules/logic_hooks.php&lt;/code&gt;&amp;nbsp;must&amp;nbsp;contain the Logic Hook definition and not the class itself&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
    $hook_version = 1;
    $hook_array = Array();
    $hook_array[&amp;#39;after_session_start&amp;#39;] = Array();
    $hook_array[&amp;#39;after_session_start&amp;#39;][] = Array(
        //Processing index. For sorting the array.
        1, 
        //Label. A string value to identify the hook.
        &amp;#39;after_session_start example&amp;#39;,
        //The PHP file where your class is located.
        &amp;#39;custom/modules/application_hooks_class.php&amp;#39;,
        //The class the method is in.
        &amp;#39;application_hooks_class&amp;#39;, 
        //The method to call.
        &amp;#39;after_session_start_method&amp;#39; 
    );&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Metadata files&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;(view defs, vardefs, etc) that are supposed to have specific&amp;nbsp;code defined as arrays should not have any function calls in them or any other logic like string concatenation or loops.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;foreach ([&amp;quot;after_retrieve&amp;quot;, &amp;quot;after_fetch_query&amp;quot;, &amp;quot;after_entry_point&amp;quot;, &amp;quot;CallsApiHelper_formatForApi_after&amp;quot;, &amp;quot;MeetingsApiHelper_formatForApi_after&amp;quot;] as $hkNameToInit) {
    ...
foreach ($aHooks as &amp;amp;$aHook) {
    ...
foreach ($hook_array as $sEvent =&amp;gt; &amp;amp;$aHooks) {&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Views/Layouts definitions&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Compiled definitions should only contain array definitions (ex: &lt;code&gt;custom/application/Ext/clients/base/layouts/header/header.ext.php&lt;/code&gt;).&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$u2af72f100c356273d46284f6fd1dfc08 = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module1\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;quot;sugar_version&amp;quot;]);
---
$u2af72f100c356273d46284f6fd1dfc08 = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module2\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;quot;sugar_version&amp;quot;]);
---
$u2af72f100c356273d46284f6fd1dfc08 = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module1\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;quot;sugar_version&amp;quot;]);
---
$version = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module3\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;#39;sugar_version&amp;#39;]);
---
$version = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module2\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;#39;sugar_version&amp;#39;]);
---
$version = new \Sugarcrm\Sugarcrm\custom\MyCompany\Module1\Libraries\PHP\Classes\Sugar\Version($GLOBALS[&amp;#39;sugar_version&amp;#39;]);
---
if (\SugarAutoloader::fileExists(&amp;#39;custom/src/MyCompany/Module3/Libraries/PHP/Classes/Sugar/Version.php&amp;#39;) &amp;amp;&amp;amp; class_exists(&amp;#39;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module3\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;#39;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;#39;sugar_version&amp;#39;])) {
---
if (\SugarAutoloader::fileExists(&amp;#39;custom/src/MyCompany/Module2/Libraries/PHP/Classes/Sugar/Version.php&amp;#39;) &amp;amp;&amp;amp; class_exists(&amp;#39;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module2\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;#39;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;#39;sugar_version&amp;#39;])) {
---
if (\SugarAutoloader::fileExists(&amp;#39;custom/src/MyCompany/Module1/Libraries/PHP/Classes/Sugar/Version.php&amp;#39;) &amp;amp;&amp;amp; class_exists(&amp;#39;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module1\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;#39;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;#39;sugar_version&amp;#39;])) {
---
if (\SugarAutoloader::fileExists(&amp;quot;custom/src/MyCompany/CallCenter/Libraries/PHP/Classes/Sugar/Version.php&amp;quot;) &amp;amp;&amp;amp; class_exists(&amp;quot;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\CallCenter\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;quot;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;quot;sugar_version&amp;quot;])) {
---
if (\SugarAutoloader::fileExists(&amp;quot;custom/src/MyCompany/Module2/Libraries/PHP/Classes/Sugar/Version.php&amp;quot;) &amp;amp;&amp;amp; class_exists(&amp;quot;\\Sugarcrm\\Sugarcrm\\custom\\MyCompany\\Module2\\Libraries\\PHP\\Classes\\Sugar\\Version&amp;quot;) &amp;amp;&amp;amp; isset($GLOBALS[&amp;quot;sugar_version&amp;quot;])) {
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;metadata definition only&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$viewdefs[&amp;#39;base&amp;#39;][&amp;#39;layout&amp;#39;][&amp;#39;header&amp;#39;] = [
    &amp;#39;components&amp;#39; =&amp;gt; [
        [
            &amp;#39;layout&amp;#39; =&amp;gt; &amp;#39;module-list&amp;#39;,
        ],
        [
            &amp;#39;layout&amp;#39; =&amp;gt; &amp;#39;quicksearch&amp;#39;,
        ],
        [
            &amp;#39;view&amp;#39; =&amp;gt; &amp;#39;notifications&amp;#39;,
        ],
        [
            &amp;#39;view&amp;#39; =&amp;gt; &amp;#39;profileactions&amp;#39;,
        ],
        [
            &amp;#39;view&amp;#39; =&amp;gt; &amp;#39;quickcreate&amp;#39;,
        ],
    ],
    &amp;#39;last_state&amp;#39; =&amp;gt; [
        &amp;#39;id&amp;#39; =&amp;gt; &amp;#39;app-header&amp;#39;,
        &amp;#39;defaults&amp;#39; =&amp;gt; [
            &amp;#39;last-home&amp;#39; =&amp;gt; &amp;#39;dashboard&amp;#39;,
        ],
    ],
];&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: Development Best Practices&lt;/div&gt;
</description></item><item><title>Declarative and Serializable Metadata</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata/revision/4</link><pubDate>Mon, 02 Jun 2025 14:26:26 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:45d31bd2-8243-4a49-82c4-90ea10831c03</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata#comments</comments><description>Revision 4 posted to Dev Tutorials by Rafael Fernandes on 6/2/2025 2:26:26 PM&lt;br /&gt;
&lt;p data-start="171" data-end="432"&gt;This guide is here to help developers follow best practices when working with Declarative and Serializable Metadata in Sugar. We&amp;#39;ve identified some common mistakes developers make and put together practical tips on how to avoid them using proven best practices.&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Avoid Using $GLOBALS Array&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;Metadata definitions should directly declare configurations explicitly instead of relying on global variables.&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$GLOBALS[&amp;quot;dictionary&amp;quot;][&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;: Use the local $dictionary variable directly:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$dictionary[&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;: Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Remove Entry Point Validations&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Entry point checks are unnecessary in metadata definitions, as these files should be simple data files..&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!defined(&amp;#39;sugarEntry&amp;#39;) || !sugarEntry) die(&amp;#39;Not A Valid Entry Point&amp;#39;);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt; Simply omit such checks from metadata entirely.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Avoid Conditional Class Checks and Dynamic Includes&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Don&amp;#39;t use conditional logic or dynamic includes in metadata definitions.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;if (!class_exists(&amp;#39;VardefManager&amp;#39;)) {
    require_once &amp;#39;include/SugarObjects/VardefManager.php&amp;#39;;
}
VardefManager::createVardef(&amp;#39;MyModule&amp;#39;,&amp;#39;MyModule&amp;#39;, [&amp;#39;basic&amp;#39;,&amp;#39;assignable&amp;#39;]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt; Rely on autoloading and straightforward declarations&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;VardefManager::createVardef(&amp;#39;MyModule&amp;#39;,&amp;#39;MyModule&amp;#39;, [&amp;#39;basic&amp;#39;,&amp;#39;assignable&amp;#39;]);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;    	    	        &lt;div style="padding: 1em; margin: 1em 0; color: #444; background-color: #fff; border: solid 1px #ddd;"&gt;
	    	        Note: Later, we plan to introduce a better way of extending vardefs from module templates. It will be more declarative and should avoid VardefManager::createVardef calls inside the vardefs files
	    &lt;/div&gt;
	&lt;/p&gt;
&lt;h2 id="mcetoc_1isogik0c0" data-start="171" data-end="432"&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1isogik5m1" data-start="171" data-end="432"&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1isogikag2" data-start="171" data-end="432"&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1isogikff3" data-start="171" data-end="432"&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1isogikjm4" data-start="171" data-end="432"&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Eliminate Imperative PHP Code&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;span&gt;Avoid embedding business logic or conditional statements directly in metadata files.&lt;/span&gt;&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$label_prefix = &amp;#39;QUESTIONS_CONFIG&amp;#39;;
$mod_strings[&amp;quot;LBL_{$label_prefix}_&amp;quot; . strtoupper(&amp;quot;view&amp;quot;)] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;Define constants explicitly without dynamic runtime manipulation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$mod_strings[&amp;#39;LBL_QUESTIONS_CONFIG_VIEW&amp;#39;] = &amp;#39;My Configuration Panel&amp;#39;;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: Development Best Practices&lt;/div&gt;
</description></item><item><title>Declarative and Serializable Metadata</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata/revision/3</link><pubDate>Mon, 02 Jun 2025 14:09:18 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:45d31bd2-8243-4a49-82c4-90ea10831c03</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata#comments</comments><description>Revision 3 posted to Dev Tutorials by Rafael Fernandes on 6/2/2025 2:09:18 PM&lt;br /&gt;
&lt;p data-start="171" data-end="432"&gt;This guide is here to help developers follow best practices when working with Declarative and Serializable Metadata in Sugar. We&amp;#39;ve identified some common mistakes developers make and put together practical tips on how to avoid them using proven best practices.&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Avoid Using $GLOBALS Array&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;Metadata definitions should directly declare configurations explicitly instead of relying on global variables.&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Problematic Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$GLOBALS[&amp;quot;dictionary&amp;quot;][&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;: Use the local $dictionary variable directly:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$dictionary[&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: Development Best Practices&lt;/div&gt;
</description></item><item><title>Declarative and Serializable Metadata</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata/revision/2</link><pubDate>Mon, 02 Jun 2025 14:06:44 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:45d31bd2-8243-4a49-82c4-90ea10831c03</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata#comments</comments><description>Revision 2 posted to Dev Tutorials by Rafael Fernandes on 6/2/2025 2:06:44 PM&lt;br /&gt;
&lt;p data-start="171" data-end="432"&gt;This guide is here to help developers follow best practices when working with Declarative and Serializable Metadata in Sugar. We&amp;#39;ve identified some common mistakes developers make and put together practical tips on how to avoid them using proven best practices.&lt;/p&gt;
&lt;h2 id="mcetoc_1isofc4jl0" data-start="171" data-end="432"&gt;Avoid Using $GLOBALS Array&lt;/h2&gt;
&lt;p data-start="171" data-end="432"&gt;Metadata definitions should directly declare configurations explicitly instead of relying on global variables.&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;strong&gt;Example&lt;/strong&gt;:&lt;/p&gt;
&lt;p data-start="171" data-end="432"&gt;&lt;pre class="ui-code" data-mode="php"&gt;$GLOBALS[&amp;quot;dictionary&amp;quot;][&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Approach&lt;/strong&gt;: Use the local $dictionary variable directly:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$dictionary[&amp;quot;MyModule&amp;quot;] = [/* ... */];&lt;/pre&gt;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: Development Best Practices&lt;/div&gt;
</description></item><item><title>Declarative and Serializable Metadata</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata/revision/1</link><pubDate>Mon, 02 Jun 2025 13:48:07 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:45d31bd2-8243-4a49-82c4-90ea10831c03</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/1006/declarative-and-serializable-metadata#comments</comments><description>Revision 1 posted to Dev Tutorials by Rafael Fernandes on 6/2/2025 1:48:07 PM&lt;br /&gt;
&lt;h1 id="Best-Practices-for-Declarative-and-Serializable-Metadata-in-Sugar" data-renderer-start-pos="1"&gt;&lt;strong data-renderer-mark="true"&gt;Declarative and Serializable Metadata&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong data-renderer-mark="true"&gt;&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item></channel></rss>