<?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>Prepare Rector for Customizations</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations</link><description /><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>Prepare Rector for Customizations</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations</link><pubDate>Wed, 10 Sep 2025 18:21:05 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:0c3c010e-3789-4bb8-8641-fa07752f8e5f</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations#comments</comments><description>Current Revision posted to Dev Tutorials by Rafael Fernandes on 9/10/2025 6:21:05 PM&lt;br /&gt;
&lt;p&gt;If you are looking to make your&amp;nbsp;customizations, not packaged in an MLP,&amp;nbsp;compatible with different versions of PHP, this guide is for you.&lt;/p&gt;
&lt;p&gt;You will take your customization code and add to the Sugar instance&amp;nbsp;&lt;span&gt;where Rector is and git has been initialized.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You need to have a inventory of your assets&amp;nbsp;to create your git/rector config.&lt;/p&gt;
&lt;h3 id="mcetoc_1guaf95jk0"&gt;Prerequisites:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customization Assets Inventory (file path of your assets)&lt;/li&gt;
&lt;li&gt;A vanilla instance if you don&amp;#39;t have an inventory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1guafg2ff1"&gt;Create your Customization Inventory&lt;/h3&gt;
&lt;p&gt;If you already have&amp;nbsp;your customization inventory, great! you can skip this section.&lt;/p&gt;
&lt;p&gt;There are a few different ways of achieving the same result, we are going to use a vanilla instance as our basis for git comparison, and your current &amp;quot;&lt;code&gt;deployed&lt;/code&gt;&amp;quot; instance with your code installed in the filesystem.&lt;/p&gt;
&lt;p&gt;In your vanilla instance, you will follow the steps from our &lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt; and have git init and commit.&lt;/p&gt;
&lt;p&gt;Once you have that in place, (&lt;code&gt;git status&lt;/code&gt; should return empty results), you are good to go on copying all the files from your&amp;nbsp;&lt;span&gt;&lt;code&gt;deployed&lt;/code&gt;&amp;nbsp;&lt;/span&gt;instance to the&amp;nbsp;vanilla&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sh-3.2$ cp -rf /path/to/current/sugar/* /path/to/vanila/sugar/&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;* it is important to have the exact same version of Sugar, otherwise, you&amp;#39;ll have &amp;quot;noise&amp;quot; in the vendors folder and other files that aren&amp;#39;t necessarily your custom code but Sugar release-related files and those can be ignored if found.&lt;/p&gt;
&lt;p&gt;After it has been copied over, execute&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;git status&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;commands to get your customization inventory:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;sh-3.2$ git status
On branch main
Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)
        modules/FD_SignupFraudDetection/
        modules/FD_TransactionFraudDetect/

nothing added to commit but untracked files present (use &amp;quot;git add&amp;quot; to track)
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Prepare your Rector config&lt;/h3&gt;
&lt;p&gt;Copy the paths, and paste them into the rector.php config file that was generated in the previous step, replacing the default paths in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;$rectorConfig-&amp;gt;paths([&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;array like this (you can ignore some of the files, like&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*ext.php&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*orderMapping.php&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;paths([
        &amp;#39;/path/to/sugar/modules/FD_SignupFraudDetection/&amp;#39;,
        &amp;#39;/path/to/sugar/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&amp;nbsp;Rector will generate a sample code with&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;__DIR__,&lt;/code&gt;&amp;nbsp;that, however, translates to &amp;quot;current folder&amp;quot; which can be different than your Sugar install. As a rule of thumb, always use fully qualified names&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;em&gt;&lt;strong&gt;without&lt;/strong&gt;&lt;/em&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;__DIR__&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Modify the &lt;code&gt;rector.php&lt;/code&gt; config file to upgrade the code to the newest supported PHP version (in our case, 8.3):&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Specify PHP 8.3 as your phpVersion:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;phpVersion(PhpVersion::PHP_83);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#39;d like to have only the incompatible rules between PHP 7.4 to PHP 8.3, you can use the following:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;rules([
        AddParamBasedOnParentClassMethodRector::class,
        SetStateToStaticRector::class,
        ArrayKeyExistsOnPropertyRector::class,
        ExportToReflectionFunctionRector::class,
        FilterVarToAddSlashesRector::class,
        MbStrrposEncodingArgumentPositionRector::class,
        MoneyFormatToNumberFormatRector::class,
        RealToFloatTypeCastRector::class,
        RestoreDefaultNullToNullableTypePropertyRector::class,
        StringifyStrNeedlesRector::class,
        GetClassOnNullRector::class,
        ListEachRector::class,
        ReplaceEachAssignmentWithKeyCurrentRector::class,
        ParseStrWithResultArgumentRector::class,
        StringifyDefineRector::class,
        WhileEachToForeachRector::class,
        ConsistentImplodeRector::class,
        CurlyToSquareBracketArrayStringRector::class,
        StaticCallOnNonStaticToInstanceCallRector::class,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Add&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;safeCount&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;rule to your config if you are in a supported Sugar version&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;&amp;lt;?php
...
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;
...
return static function (RectorConfig $rectorConfig): void {
...
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
...&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example (incompatibilities only)&lt;/h3&gt;
&lt;p&gt;By following those steps, you should have a rector.php similar to this to run&amp;nbsp;&lt;span&gt;incompatible rules between PHP 7.4 to PHP 8.3&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
declare(strict_types=1);

use Rector\CodingStyle\Rector\FuncCall\ConsistentImplodeRector;
use Rector\Php72\Rector\Assign\ListEachRector;
use Rector\Php72\Rector\Assign\ReplaceEachAssignmentWithKeyCurrentRector;
use Rector\Php72\Rector\FuncCall\GetClassOnNullRector;
use Rector\Php72\Rector\FuncCall\ParseStrWithResultArgumentRector;
use Rector\Php72\Rector\FuncCall\StringifyDefineRector;
use Rector\Php72\Rector\While_\WhileEachToForeachRector;
use Rector\Php73\Rector\FuncCall\StringifyStrNeedlesRector;
use Rector\Php74\Rector\Double\RealToFloatTypeCastRector;
use Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector;
use Rector\Php74\Rector\FuncCall\FilterVarToAddSlashesRector;
use Rector\Php74\Rector\FuncCall\MbStrrposEncodingArgumentPositionRector;
use Rector\Php74\Rector\FuncCall\MoneyFormatToNumberFormatRector;
use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector;
use Rector\Php74\Rector\StaticCall\ExportToReflectionFunctionRector;
use Rector\Php80\Rector\ClassMethod\AddParamBasedOnParentClassMethodRector;
use Rector\Php80\Rector\ClassMethod\SetStateToStaticRector;
use Rector\Config\RectorConfig;
use Rector\ValueObject\PhpVersion;
use Rector\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector;
use Rector\Caching\ValueObject\Storage\MemoryCacheStorage;
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;
use Rector\Php70\Rector\StaticCall\StaticCallOnNonStaticToInstanceCallRector;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        &amp;#39;/path/to/sugar/modules/FD_SignupFraudDetection/&amp;#39;,
        &amp;#39;/path/to/sugar/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);

    $rectorConfig-&amp;gt;cacheClass(MemoryCacheStorage::class);
    $rectorConfig-&amp;gt;disableParallel();
    $rectorConfig-&amp;gt;phpVersion(PhpVersion::PHP_83);

    $rectorConfig-&amp;gt;rules([
        AddParamBasedOnParentClassMethodRector::class,
        SetStateToStaticRector::class,
        ArrayKeyExistsOnPropertyRector::class,
        ExportToReflectionFunctionRector::class,
        FilterVarToAddSlashesRector::class,
        MbStrrposEncodingArgumentPositionRector::class,
        MoneyFormatToNumberFormatRector::class,
        RealToFloatTypeCastRector::class,
        RestoreDefaultNullToNullableTypePropertyRector::class,
        StringifyStrNeedlesRector::class,
        GetClassOnNullRector::class,
        ListEachRector::class,
        ReplaceEachAssignmentWithKeyCurrentRector::class,
        ParseStrWithResultArgumentRector::class,
        StringifyDefineRector::class,
        WhileEachToForeachRector::class,
        ConsistentImplodeRector::class,
        CurlyToSquareBracketArrayStringRector::class,
        StaticCallOnNonStaticToInstanceCallRector::class,
    ]);
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1gudgk28f0"&gt;You can move on to the&amp;nbsp;Execution Phase:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/836/executing-rector"&gt;Execute Rector&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Prepare Rector for Customizations</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations/revision/9</link><pubDate>Mon, 17 Mar 2025 13:04:30 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:0c3c010e-3789-4bb8-8641-fa07752f8e5f</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations#comments</comments><description>Revision 9 posted to Dev Tutorials by Rafael Fernandes on 3/17/2025 1:04:30 PM&lt;br /&gt;
&lt;p&gt;If you are looking to make your&amp;nbsp;customizations, not packaged in an MLP,&amp;nbsp;compatible with different versions of PHP, this guide is for you.&lt;/p&gt;
&lt;p&gt;You will take your customization code and add to the Sugar instance&amp;nbsp;&lt;span&gt;where Rector is and git has been initialized.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You need to have a inventory of your assets&amp;nbsp;to create your git/rector config.&lt;/p&gt;
&lt;h3 id="mcetoc_1guaf95jk0"&gt;Prerequisites:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customization Assets Inventory (file path of your assets)&lt;/li&gt;
&lt;li&gt;A vanila instance if you don&amp;#39;t have an inventory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1guafg2ff1"&gt;Create your Customization Inventory&lt;/h3&gt;
&lt;p&gt;If you already have&amp;nbsp;your customization inventory, great! you can skip this section.&lt;/p&gt;
&lt;p&gt;There are a few different ways of achieving the same result, we are going to use a vanilla instance as our basis for git comparison, and your current &amp;quot;&lt;code&gt;deployed&lt;/code&gt;&amp;quot; instance with your code installed in the filesystem.&lt;/p&gt;
&lt;p&gt;In your vanilla instance, you will follow the steps from our &lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt; and have git init and commit.&lt;/p&gt;
&lt;p&gt;Once you have that in place, (&lt;code&gt;git status&lt;/code&gt; should return empty results), you are good to go on copying all the files from your&amp;nbsp;&lt;span&gt;&lt;code&gt;deployed&lt;/code&gt;&amp;nbsp;&lt;/span&gt;instance to the&amp;nbsp;vanilla&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sh-3.2$ cp -rf /path/to/current/sugar/* /path/to/vanila/sugar/&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;* it is important to have the exact same version of Sugar, otherwise, you&amp;#39;ll have &amp;quot;noise&amp;quot; in the vendors folder and other files that aren&amp;#39;t necessarily your custom code but Sugar release-related files and those can be ignored if found.&lt;/p&gt;
&lt;p&gt;After it has been copied over, execute&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;git status&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;commands to get your customization inventory:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;sh-3.2$ git status
On branch main
Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)
        modules/FD_SignupFraudDetection/
        modules/FD_TransactionFraudDetect/

nothing added to commit but untracked files present (use &amp;quot;git add&amp;quot; to track)
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Prepare your Rector config&lt;/h3&gt;
&lt;p&gt;Copy the paths, and paste them into the rector.php config file that was generated in the previous step, replacing the default paths in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;$rectorConfig-&amp;gt;paths([&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;array like this (you can ignore some of the files, like&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*ext.php&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*orderMapping.php&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;* Please, notice the &amp;#39;/&amp;#39; after&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;constant usage. It is required as&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;does not have a trailing slash.&lt;/p&gt;
&lt;p&gt;Modify the &lt;code&gt;rector.php&lt;/code&gt; config file to upgrade the code to the newest supported PHP version (in our case, 8.3):&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Specify PHP 8.3 as your phpVersion:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;phpVersion(PhpVersion::PHP_83);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#39;d like to have only the incompatible rules between PHP 7.4 to PHP 8.3, you can use the following:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;rules([
        AddParamBasedOnParentClassMethodRector::class,
        SetStateToStaticRector::class,
        ArrayKeyExistsOnPropertyRector::class,
        ExportToReflectionFunctionRector::class,
        FilterVarToAddSlashesRector::class,
        MbStrrposEncodingArgumentPositionRector::class,
        MoneyFormatToNumberFormatRector::class,
        RealToFloatTypeCastRector::class,
        RestoreDefaultNullToNullableTypePropertyRector::class,
        StringifyStrNeedlesRector::class,
        GetClassOnNullRector::class,
        ListEachRector::class,
        ReplaceEachAssignmentWithKeyCurrentRector::class,
        ParseStrWithResultArgumentRector::class,
        StringifyDefineRector::class,
        WhileEachToForeachRector::class,
        ConsistentImplodeRector::class,
        CurlyToSquareBracketArrayStringRector::class,
        StaticCallOnNonStaticToInstanceCallRector::class,
    ]);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Add&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;safeCount&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;rule to your config if you are in a supported Sugar version&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;&amp;lt;?php
...
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;
...
return static function (RectorConfig $rectorConfig): void {
...
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
...&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example (incompatibilities only)&lt;/h3&gt;
&lt;p&gt;By following those steps, you should have a rector.php similar to this to run&amp;nbsp;&lt;span&gt;incompatible rules between PHP 7.4 to PHP 8.3&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
declare(strict_types=1);

use Rector\CodingStyle\Rector\FuncCall\ConsistentImplodeRector;
use Rector\Php72\Rector\Assign\ListEachRector;
use Rector\Php72\Rector\Assign\ReplaceEachAssignmentWithKeyCurrentRector;
use Rector\Php72\Rector\FuncCall\GetClassOnNullRector;
use Rector\Php72\Rector\FuncCall\ParseStrWithResultArgumentRector;
use Rector\Php72\Rector\FuncCall\StringifyDefineRector;
use Rector\Php72\Rector\While_\WhileEachToForeachRector;
use Rector\Php73\Rector\FuncCall\StringifyStrNeedlesRector;
use Rector\Php74\Rector\Double\RealToFloatTypeCastRector;
use Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector;
use Rector\Php74\Rector\FuncCall\FilterVarToAddSlashesRector;
use Rector\Php74\Rector\FuncCall\MbStrrposEncodingArgumentPositionRector;
use Rector\Php74\Rector\FuncCall\MoneyFormatToNumberFormatRector;
use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector;
use Rector\Php74\Rector\StaticCall\ExportToReflectionFunctionRector;
use Rector\Php80\Rector\ClassMethod\AddParamBasedOnParentClassMethodRector;
use Rector\Php80\Rector\ClassMethod\SetStateToStaticRector;
use Rector\Config\RectorConfig;
use Rector\ValueObject\PhpVersion;
use Rector\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector;
use Rector\Caching\ValueObject\Storage\MemoryCacheStorage;
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;
use Rector\Php70\Rector\StaticCall\StaticCallOnNonStaticToInstanceCallRector;


return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);

    $rectorConfig-&amp;gt;cacheClass(MemoryCacheStorage::class);
    $rectorConfig-&amp;gt;disableParallel();
    $rectorConfig-&amp;gt;phpVersion(PhpVersion::PHP_83);

    $rectorConfig-&amp;gt;rules([
        AddParamBasedOnParentClassMethodRector::class,
        SetStateToStaticRector::class,
        ArrayKeyExistsOnPropertyRector::class,
        ExportToReflectionFunctionRector::class,
        FilterVarToAddSlashesRector::class,
        MbStrrposEncodingArgumentPositionRector::class,
        MoneyFormatToNumberFormatRector::class,
        RealToFloatTypeCastRector::class,
        RestoreDefaultNullToNullableTypePropertyRector::class,
        StringifyStrNeedlesRector::class,
        GetClassOnNullRector::class,
        ListEachRector::class,
        ReplaceEachAssignmentWithKeyCurrentRector::class,
        ParseStrWithResultArgumentRector::class,
        StringifyDefineRector::class,
        WhileEachToForeachRector::class,
        ConsistentImplodeRector::class,
        CurlyToSquareBracketArrayStringRector::class,
        StaticCallOnNonStaticToInstanceCallRector::class,
    ]);
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1gudgk28f0"&gt;You can move on to the&amp;nbsp;Execution Phase:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/836/executing-rector"&gt;Execute Rector&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Prepare Rector for Customizations</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations/revision/8</link><pubDate>Thu, 26 Oct 2023 17:45:51 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:0c3c010e-3789-4bb8-8641-fa07752f8e5f</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations#comments</comments><description>Revision 8 posted to Dev Tutorials by Rafael Fernandes on 10/26/2023 5:45:51 PM&lt;br /&gt;
&lt;p&gt;If you are looking to make your&amp;nbsp;customizations, not packaged in an MLP,&amp;nbsp;compatible with different versions of PHP, this guide is for you.&lt;/p&gt;
&lt;p&gt;You will take your customization code and add to the Sugar instance&amp;nbsp;&lt;span&gt;where Rector is and git has been initialized.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You need to have a inventory of your assets&amp;nbsp;to create your git/rector config.&lt;/p&gt;
&lt;h3 id="mcetoc_1guaf95jk0"&gt;Prerequisites:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customization Assets Inventory (file path of your assets)&lt;/li&gt;
&lt;li&gt;A vanila instance if you don&amp;#39;t have an inventory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1guafg2ff1"&gt;Create your Customization Inventory&lt;/h3&gt;
&lt;p&gt;If you already have&amp;nbsp;your customization inventory, great! you can skip this section.&lt;/p&gt;
&lt;p&gt;There are a few different ways of achieving the same result, we are going to use a vanilla instance as our basis for git comparison, and your current &amp;quot;&lt;code&gt;deployed&lt;/code&gt;&amp;quot; instance with your code installed in the filesystem.&lt;/p&gt;
&lt;p&gt;In your vanilla instance, you will follow the steps from our &lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt; and have git init and commit.&lt;/p&gt;
&lt;p&gt;Once you have that in place, (&lt;code&gt;git status&lt;/code&gt; should return empty results), you are good to go on copying all the files from your&amp;nbsp;&lt;span&gt;&lt;code&gt;deployed&lt;/code&gt;&amp;nbsp;&lt;/span&gt;instance to the&amp;nbsp;vanilla&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sh-3.2$ cp -rf /path/to/current/sugar/* /path/to/vanila/sugar/&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;* it is important to have the exact same version of Sugar, otherwise, you&amp;#39;ll have &amp;quot;noise&amp;quot; in the vendors folder and other files that aren&amp;#39;t necessarily your custom code but Sugar release-related files and those can be ignored if found.&lt;/p&gt;
&lt;p&gt;After it has been copied over, execute&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;git status&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;commands to get your customization inventory:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;sh-3.2$ git status
On branch main
Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)
        modules/FD_SignupFraudDetection/
        modules/FD_TransactionFraudDetect/

nothing added to commit but untracked files present (use &amp;quot;git add&amp;quot; to track)
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Prepare your Rector config&lt;/h3&gt;
&lt;p&gt;Copy the paths, and paste them into the rector.php config file that was generated in the previous step, replacing the default paths in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;$rectorConfig-&amp;gt;paths([&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;array like this (you can ignore some of the files, like&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*ext.php&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*orderMapping.php&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;* Please, notice the &amp;#39;/&amp;#39; after&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;constant usage. It is required as&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;does not have a trailing slash.&lt;/p&gt;
&lt;p&gt;Modify the rector.php config file to upgrade the code to the newest supported PHP version (in our case, 8.2):&lt;/p&gt;
&lt;p&gt;Remove/Comment&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// register a single rule
$rectorConfig-&amp;gt;rule(InlineConstructorDefaultToPropertyRector::class);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Specify PHP 8.2 as your phpVersion:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;phpVersion(PhpVersion::PHP_82);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The following rules should be skipped to prevent known issues with Sugar (it will skip those but will run all the other rules available in your rector version).&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#39;d like to have only the incompatible rules between PHP 7.4 to PHP 8.2, you can use the following:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;rules([
        AddParamBasedOnParentClassMethodRector::class,
        SetStateToStaticRector::class,
        Php8ResourceReturnToObjectRector::class,
        Php81ResourceReturnToObjectRector::class,
        ArrayKeyExistsOnPropertyRector::class,
        ExportToReflectionFunctionRector::class,
        FilterVarToAddSlashesRector::class,
        MbStrrposEncodingArgumentPositionRector::class,
        MoneyFormatToNumberFormatRector::class,
        RealToFloatTypeCastRector::class,
        RestoreDefaultNullToNullableTypePropertyRector::class,
        StringifyStrNeedlesRector::class,
        GetClassOnNullRector::class,
        ListEachRector::class,
        ReplaceEachAssignmentWithKeyCurrentRector::class,
        ParseStrWithResultArgumentRector::class,
        StringifyDefineRector::class,
        WhileEachToForeachRector::class,
        ConsistentImplodeRector::class,
        CurlyToSquareBracketArrayStringRector::class,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Add&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;safeCount&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;rule to your config if you are in a supported Sugar version&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;&amp;lt;?php
...
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;
...
return static function (RectorConfig $rectorConfig): void {
...
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
...&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;By following those steps, you should have a rector.php similar to this to run all Rector rules against your code:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);

    $rectorConfig-&amp;gt;sets([
        LevelSetList::UP_TO_PHP_82,
        SetList::PHP_82,
    ]);

    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example (incompatibilities only)&lt;/h3&gt;
&lt;p&gt;By following those steps, you should have a rector.php similar to this to run&amp;nbsp;&lt;span&gt;incompatible rules between PHP 7.4 to PHP 8.2&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
declare(strict_types=1);

use Rector\CodingStyle\Rector\FuncCall\ConsistentImplodeRector;
use Rector\Php72\Rector\Assign\ListEachRector;
use Rector\Php72\Rector\Assign\ReplaceEachAssignmentWithKeyCurrentRector;
use Rector\Php72\Rector\FuncCall\GetClassOnNullRector;
use Rector\Php72\Rector\FuncCall\ParseStrWithResultArgumentRector;
use Rector\Php72\Rector\FuncCall\StringifyDefineRector;
use Rector\Php72\Rector\While_\WhileEachToForeachRector;
use Rector\Php73\Rector\FuncCall\StringifyStrNeedlesRector;
use Rector\Php74\Rector\Double\RealToFloatTypeCastRector;
use Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector;
use Rector\Php74\Rector\FuncCall\FilterVarToAddSlashesRector;
use Rector\Php74\Rector\FuncCall\MbStrrposEncodingArgumentPositionRector;
use Rector\Php74\Rector\FuncCall\MoneyFormatToNumberFormatRector;
use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector;
use Rector\Php74\Rector\StaticCall\ExportToReflectionFunctionRector;
use Rector\Php80\Rector\ClassMethod\AddParamBasedOnParentClassMethodRector;
use Rector\Php80\Rector\ClassMethod\SetStateToStaticRector;
use Rector\Config\RectorConfig;
use Rector\Core\ValueObject\PhpVersion;
use Rector\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector;
use Rector\Caching\ValueObject\Storage\MemoryCacheStorage;
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;
use Rector\Php70\Rector\StaticCall\StaticCallOnNonStaticToInstanceCallRector;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);
    $rectorConfig-&amp;gt;cacheClass(MemoryCacheStorage::class);
    $rectorConfig-&amp;gt;disableParallel();
    $rectorConfig-&amp;gt;phpVersion(PhpVersion::PHP_82);
    $rectorConfig-&amp;gt;rules([
        AddParamBasedOnParentClassMethodRector::class,
        SetStateToStaticRector::class,
        ArrayKeyExistsOnPropertyRector::class,
        ExportToReflectionFunctionRector::class,
        FilterVarToAddSlashesRector::class,
        MbStrrposEncodingArgumentPositionRector::class,
        MoneyFormatToNumberFormatRector::class,
        RealToFloatTypeCastRector::class,
        RestoreDefaultNullToNullableTypePropertyRector::class,
        StringifyStrNeedlesRector::class,
        GetClassOnNullRector::class,
        ListEachRector::class,
        ReplaceEachAssignmentWithKeyCurrentRector::class,
        ParseStrWithResultArgumentRector::class,
        StringifyDefineRector::class,
        WhileEachToForeachRector::class,
        ConsistentImplodeRector::class,
        CurlyToSquareBracketArrayStringRector::class,
        StaticCallOnNonStaticToInstanceCallRector::class
    ]);
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1gudgk28f0"&gt;You can move on to the&amp;nbsp;Execution Phase:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/836/executing-rector"&gt;Execute Rector&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Prepare Rector for Customizations</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations/revision/7</link><pubDate>Tue, 10 Oct 2023 16:53:08 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:0c3c010e-3789-4bb8-8641-fa07752f8e5f</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations#comments</comments><description>Revision 7 posted to Dev Tutorials by Rafael Fernandes on 10/10/2023 4:53:08 PM&lt;br /&gt;
&lt;p&gt;If you are looking to make your&amp;nbsp;customizations, not packaged in an MLP,&amp;nbsp;compatible with different versions of PHP, this guide is for you.&lt;/p&gt;
&lt;p&gt;You will take your customization code and add to the Sugar instance&amp;nbsp;&lt;span&gt;where Rector is and git has been initialized.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You need to have a inventory of your assets&amp;nbsp;to create your git/rector config.&lt;/p&gt;
&lt;h3 id="mcetoc_1guaf95jk0"&gt;Prerequisites:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customization Assets Inventory (file path of your assets)&lt;/li&gt;
&lt;li&gt;A vanila instance if you don&amp;#39;t have an inventory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1guafg2ff1"&gt;Create your Customization Inventory&lt;/h3&gt;
&lt;p&gt;If you already have&amp;nbsp;your customization inventory, great! you can skip this section.&lt;/p&gt;
&lt;p&gt;There are a few different ways of achieving the same result, we are going to use a vanilla instance as our basis for git comparison, and your current &amp;quot;&lt;code&gt;deployed&lt;/code&gt;&amp;quot; instance with your code installed in the filesystem.&lt;/p&gt;
&lt;p&gt;In your vanilla instance, you will follow the steps from our &lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt; and have git init and commit.&lt;/p&gt;
&lt;p&gt;Once you have that in place, (&lt;code&gt;git status&lt;/code&gt; should return empty results), you are good to go on copying all the files from your&amp;nbsp;&lt;span&gt;&lt;code&gt;deployed&lt;/code&gt;&amp;nbsp;&lt;/span&gt;instance to the&amp;nbsp;vanilla&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sh-3.2$ cp -rf /path/to/current/sugar/* /path/to/vanila/sugar/&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;* it is important to have the exact same version of Sugar, otherwise, you&amp;#39;ll have &amp;quot;noise&amp;quot; in the vendors folder and other files that aren&amp;#39;t necessarily your custom code but Sugar release-related files and those can be ignored if found.&lt;/p&gt;
&lt;p&gt;After it has been copied over, execute&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;git status&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;commands to get your customization inventory:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;sh-3.2$ git status
On branch main
Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)
        modules/FD_SignupFraudDetection/
        modules/FD_TransactionFraudDetect/

nothing added to commit but untracked files present (use &amp;quot;git add&amp;quot; to track)
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Prepare your Rector config&lt;/h3&gt;
&lt;p&gt;Copy the paths, and paste them into the rector.php config file that was generated in the previous step, replacing the default paths in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;$rectorConfig-&amp;gt;paths([&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;array like this (you can ignore some of the files, like&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*ext.php&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*orderMapping.php&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;* Please, notice the &amp;#39;/&amp;#39; after&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;constant usage. It is required as&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;does not have a trailing slash.&lt;/p&gt;
&lt;p&gt;Modify the rector.php config file to upgrade the code to the newest supported PHP version (in our case, 8.2):&lt;/p&gt;
&lt;p&gt;Remove/Comment&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// register a single rule
$rectorConfig-&amp;gt;rule(InlineConstructorDefaultToPropertyRector::class);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Specify PHP 8.2 as your phpVersion:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;phpVersion(PhpVersion::PHP_82);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The following rules should be skipped to prevent known issues with Sugar (it will skip those but will run all the other rules available in your rector version).&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#39;d like to have only the incompatible rules between PHP 7.4 to PHP 8.2, you can use the following:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;rules([
        AddParamBasedOnParentClassMethodRector::class,
        SetStateToStaticRector::class,
        Php8ResourceReturnToObjectRector::class,
        Php81ResourceReturnToObjectRector::class,
        ArrayKeyExistsOnPropertyRector::class,
        ExportToReflectionFunctionRector::class,
        FilterVarToAddSlashesRector::class,
        MbStrrposEncodingArgumentPositionRector::class,
        MoneyFormatToNumberFormatRector::class,
        RealToFloatTypeCastRector::class,
        RestoreDefaultNullToNullableTypePropertyRector::class,
        StringifyStrNeedlesRector::class,
        GetClassOnNullRector::class,
        ListEachRector::class,
        ReplaceEachAssignmentWithKeyCurrentRector::class,
        ParseStrWithResultArgumentRector::class,
        StringifyDefineRector::class,
        WhileEachToForeachRector::class,
        ConsistentImplodeRector::class,
        CurlyToSquareBracketArrayStringRector::class,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Add&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;safeCount&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;rule to your config if you are in a supported Sugar version&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;&amp;lt;?php
...
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;
...
return static function (RectorConfig $rectorConfig): void {
...
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
...&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;By following those steps, you should have a rector.php similar to this to run all Rector rules against your code:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);

    $rectorConfig-&amp;gt;sets([
        LevelSetList::UP_TO_PHP_82,
        SetList::PHP_82,
    ]);

    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example (incompatibilities only)&lt;/h3&gt;
&lt;p&gt;By following those steps, you should have a rector.php similar to this to run&amp;nbsp;&lt;span&gt;incompatible rules between PHP 7.4 to PHP 8.2&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
declare(strict_types=1);

use Rector\CodingStyle\Rector\FuncCall\ConsistentImplodeRector;
use Rector\Php72\Rector\Assign\ListEachRector;
use Rector\Php72\Rector\Assign\ReplaceEachAssignmentWithKeyCurrentRector;
use Rector\Php72\Rector\FuncCall\GetClassOnNullRector;
use Rector\Php72\Rector\FuncCall\ParseStrWithResultArgumentRector;
use Rector\Php72\Rector\FuncCall\StringifyDefineRector;
use Rector\Php72\Rector\While_\WhileEachToForeachRector;
use Rector\Php73\Rector\FuncCall\StringifyStrNeedlesRector;
use Rector\Php74\Rector\Double\RealToFloatTypeCastRector;
use Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector;
use Rector\Php74\Rector\FuncCall\FilterVarToAddSlashesRector;
use Rector\Php74\Rector\FuncCall\MbStrrposEncodingArgumentPositionRector;
use Rector\Php74\Rector\FuncCall\MoneyFormatToNumberFormatRector;
use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector;
use Rector\Php74\Rector\StaticCall\ExportToReflectionFunctionRector;
use Rector\Php80\Rector\ClassMethod\AddParamBasedOnParentClassMethodRector;
use Rector\Php80\Rector\ClassMethod\SetStateToStaticRector;
use Rector\Php80\Rector\FuncCall\Php8ResourceReturnToObjectRector;
use Rector\Config\RectorConfig;
use Rector\Core\ValueObject\PhpVersion;
use Rector\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector;
use Rector\Caching\ValueObject\Storage\MemoryCacheStorage;
use Rector\Php81\Rector\FuncCall\Php81ResourceReturnToObjectRector;
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;
use Rector\Php70\Rector\StaticCall\StaticCallOnNonStaticToInstanceCallRector;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);
    $rectorConfig-&amp;gt;cacheClass(MemoryCacheStorage::class);
    $rectorConfig-&amp;gt;disableParallel();
    $rectorConfig-&amp;gt;phpVersion(PhpVersion::PHP_82);
    $rectorConfig-&amp;gt;rules([
        AddParamBasedOnParentClassMethodRector::class,
        SetStateToStaticRector::class,
        Php8ResourceReturnToObjectRector::class,
        Php81ResourceReturnToObjectRector::class,
        ArrayKeyExistsOnPropertyRector::class,
        ExportToReflectionFunctionRector::class,
        FilterVarToAddSlashesRector::class,
        MbStrrposEncodingArgumentPositionRector::class,
        MoneyFormatToNumberFormatRector::class,
        RealToFloatTypeCastRector::class,
        RestoreDefaultNullToNullableTypePropertyRector::class,
        StringifyStrNeedlesRector::class,
        GetClassOnNullRector::class,
        ListEachRector::class,
        ReplaceEachAssignmentWithKeyCurrentRector::class,
        ParseStrWithResultArgumentRector::class,
        StringifyDefineRector::class,
        WhileEachToForeachRector::class,
        ConsistentImplodeRector::class,
        CurlyToSquareBracketArrayStringRector::class,
        StaticCallOnNonStaticToInstanceCallRector::class
    ]);
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1gudgk28f0"&gt;You can move on to the&amp;nbsp;Execution Phase:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/836/executing-rector"&gt;Execute Rector&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Prepare Rector for Customizations</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations/revision/6</link><pubDate>Thu, 07 Sep 2023 15:31:18 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:0c3c010e-3789-4bb8-8641-fa07752f8e5f</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations#comments</comments><description>Revision 6 posted to Dev Tutorials by Rafael Fernandes on 9/7/2023 3:31:18 PM&lt;br /&gt;
&lt;p&gt;If you are looking to make your&amp;nbsp;customizations, not packaged in an MLP,&amp;nbsp;compatible with different versions of PHP, this guide is for you.&lt;/p&gt;
&lt;p&gt;You will take your customization code and add to the Sugar instance&amp;nbsp;&lt;span&gt;where Rector is and git has been initialized.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You need to have a inventory of your assets&amp;nbsp;to create your git/rector config.&lt;/p&gt;
&lt;h3 id="mcetoc_1guaf95jk0"&gt;Prerequisites:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customization Assets Inventory (file path of your assets)&lt;/li&gt;
&lt;li&gt;A vanila instance if you don&amp;#39;t have an inventory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1guafg2ff1"&gt;Create your Customization Inventory&lt;/h3&gt;
&lt;p&gt;If you already have&amp;nbsp;your customization inventory, great! you can skip this section.&lt;/p&gt;
&lt;p&gt;There are a few different ways of achieving the same result, we are going to use a vanilla instance as our basis for git comparison, and your current &amp;quot;&lt;code&gt;deployed&lt;/code&gt;&amp;quot; instance with your code installed in the filesystem.&lt;/p&gt;
&lt;p&gt;In your vanilla instance, you will follow the steps from our &lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt; and have git init and commit.&lt;/p&gt;
&lt;p&gt;Once you have that in place, (&lt;code&gt;git status&lt;/code&gt; should return empty results), you are good to go on copying all the files from your&amp;nbsp;&lt;span&gt;&lt;code&gt;deployed&lt;/code&gt;&amp;nbsp;&lt;/span&gt;instance to the&amp;nbsp;vanilla&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sh-3.2$ cp -rf /path/to/current/sugar/* /path/to/vanila/sugar/&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;* it is important to have the exact same version of Sugar, otherwise, you&amp;#39;ll have &amp;quot;noise&amp;quot; in the vendors folder and other files that aren&amp;#39;t necessarily your custom code but Sugar release-related files and those can be ignored if found.&lt;/p&gt;
&lt;p&gt;After it has been copied over, execute&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;git status&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;commands to get your customization inventory:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;sh-3.2$ git status
On branch main
Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)
        modules/FD_SignupFraudDetection/
        modules/FD_TransactionFraudDetect/

nothing added to commit but untracked files present (use &amp;quot;git add&amp;quot; to track)
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Prepare your Rector config&lt;/h3&gt;
&lt;p&gt;Copy the paths, and paste them into the rector.php config file that was generated in the previous step, replacing the default paths in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;$rectorConfig-&amp;gt;paths([&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;array like this (you can ignore some of the files, like&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*ext.php&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*orderMapping.php&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;* Please, notice the &amp;#39;/&amp;#39; after&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;constant usage. It is required as&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;does not have a trailing slash.&lt;/p&gt;
&lt;p&gt;Modify the rector.php config file to upgrade the code to the newest supported PHP version (in our case, 8.2):&lt;/p&gt;
&lt;p&gt;Remove/Comment&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// register a single rule
$rectorConfig-&amp;gt;rule(InlineConstructorDefaultToPropertyRector::class);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Specify PHP 8.2 as your phpVersion:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;phpVersion(PhpVersion::PHP_82);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The following rules should be skipped to prevent known issues with Sugar (it will skip those but will run all the other rules available in your rector version).&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#39;d like to have only the incompatible rules between PHP 7.4 to PHP 8.2, you can use the following:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;rules([
        AddParamBasedOnParentClassMethodRector::class,
        SetStateToStaticRector::class,
        Php8ResourceReturnToObjectRector::class,
        Php81ResourceReturnToObjectRector::class,
        ArrayKeyExistsOnPropertyRector::class,
        ExportToReflectionFunctionRector::class,
        FilterVarToAddSlashesRector::class,
        MbStrrposEncodingArgumentPositionRector::class,
        MoneyFormatToNumberFormatRector::class,
        RealToFloatTypeCastRector::class,
        RestoreDefaultNullToNullableTypePropertyRector::class,
        StringifyStrNeedlesRector::class,
        GetClassOnNullRector::class,
        ListEachRector::class,
        ReplaceEachAssignmentWithKeyCurrentRector::class,
        ParseStrWithResultArgumentRector::class,
        StringifyDefineRector::class,
        WhileEachToForeachRector::class,
        ConsistentImplodeRector::class,
        CurlyToSquareBracketArrayStringRector::class,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Add&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;safeCount&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;rule to your config if you are in a supported Sugar version&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;&amp;lt;?php
...
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;
...
return static function (RectorConfig $rectorConfig): void {
...
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
...&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;By following those steps, you should have a rector.php similar to this to run all Rector rules against your code:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);

    $rectorConfig-&amp;gt;sets([
        LevelSetList::UP_TO_PHP_82,
        SetList::PHP_82,
    ]);

    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example (incompatibilities only)&lt;/h3&gt;
&lt;p&gt;By following those steps, you should have a rector.php similar to this to run&amp;nbsp;&lt;span&gt;incompatible rules between PHP 7.4 to PHP 8.2&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
declare(strict_types=1);

use Rector\CodingStyle\Rector\FuncCall\ConsistentImplodeRector;
use Rector\Php72\Rector\Assign\ListEachRector;
use Rector\Php72\Rector\Assign\ReplaceEachAssignmentWithKeyCurrentRector;
use Rector\Php72\Rector\FuncCall\GetClassOnNullRector;
use Rector\Php72\Rector\FuncCall\ParseStrWithResultArgumentRector;
use Rector\Php72\Rector\FuncCall\StringifyDefineRector;
use Rector\Php72\Rector\While_\WhileEachToForeachRector;
use Rector\Php73\Rector\FuncCall\StringifyStrNeedlesRector;
use Rector\Php74\Rector\Double\RealToFloatTypeCastRector;
use Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector;
use Rector\Php74\Rector\FuncCall\FilterVarToAddSlashesRector;
use Rector\Php74\Rector\FuncCall\MbStrrposEncodingArgumentPositionRector;
use Rector\Php74\Rector\FuncCall\MoneyFormatToNumberFormatRector;
use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector;
use Rector\Php74\Rector\StaticCall\ExportToReflectionFunctionRector;
use Rector\Php80\Rector\ClassMethod\AddParamBasedOnParentClassMethodRector;
use Rector\Php80\Rector\ClassMethod\SetStateToStaticRector;
use Rector\Php80\Rector\FuncCall\Php8ResourceReturnToObjectRector;
use Rector\Config\RectorConfig;
use Rector\Core\ValueObject\PhpVersion;
use Rector\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector;
use Rector\Caching\ValueObject\Storage\MemoryCacheStorage;
use Rector\Php81\Rector\FuncCall\Php81ResourceReturnToObjectRector;
use Rector\Renaming\Rector\FuncCall\RenameFunctionRector;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);
    $rectorConfig-&amp;gt;cacheClass(MemoryCacheStorage::class);
    $rectorConfig-&amp;gt;disableParallel();
    $rectorConfig-&amp;gt;phpVersion(PhpVersion::PHP_82);
    $rectorConfig-&amp;gt;rules([
        AddParamBasedOnParentClassMethodRector::class,
        SetStateToStaticRector::class,
        Php8ResourceReturnToObjectRector::class,
        Php81ResourceReturnToObjectRector::class,
        ArrayKeyExistsOnPropertyRector::class,
        ExportToReflectionFunctionRector::class,
        FilterVarToAddSlashesRector::class,
        MbStrrposEncodingArgumentPositionRector::class,
        MoneyFormatToNumberFormatRector::class,
        RealToFloatTypeCastRector::class,
        RestoreDefaultNullToNullableTypePropertyRector::class,
        StringifyStrNeedlesRector::class,
        GetClassOnNullRector::class,
        ListEachRector::class,
        ReplaceEachAssignmentWithKeyCurrentRector::class,
        ParseStrWithResultArgumentRector::class,
        StringifyDefineRector::class,
        WhileEachToForeachRector::class,
        ConsistentImplodeRector::class,
        CurlyToSquareBracketArrayStringRector::class,
    ]);
    $rectorConfig-&amp;gt;ruleWithConfiguration(RenameFunctionRector::class, [
        &amp;#39;count&amp;#39; =&amp;gt; &amp;#39;safeCount&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1gudgk28f0"&gt;You can move on to the&amp;nbsp;Execution Phase:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/836/executing-rector"&gt;Execute Rector&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Prepare Rector for Customizations</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations/revision/5</link><pubDate>Tue, 11 Jul 2023 19:44:45 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:0c3c010e-3789-4bb8-8641-fa07752f8e5f</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations#comments</comments><description>Revision 5 posted to Dev Tutorials by Rafael Fernandes on 7/11/2023 7:44:45 PM&lt;br /&gt;
&lt;p&gt;If you are looking to make your&amp;nbsp;customizations, not packaged in an MLP,&amp;nbsp;compatible with different versions of PHP, this guide is for you.&lt;/p&gt;
&lt;p&gt;You will take your customization code and add to the Sugar instance&amp;nbsp;&lt;span&gt;where Rector is and git has been initialized.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You need to have a inventory of your assets&amp;nbsp;to create your git/rector config.&lt;/p&gt;
&lt;h3 id="mcetoc_1guaf95jk0"&gt;Prerequisites:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customization Assets Inventory (file path of your assets)&lt;/li&gt;
&lt;li&gt;A vanila instance if you don&amp;#39;t have an inventory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1guafg2ff1"&gt;Create your Customization Inventory&lt;/h3&gt;
&lt;p&gt;If you already have&amp;nbsp;your customization inventory, great! you can skip this section.&lt;/p&gt;
&lt;p&gt;There are a few different ways of achieving the same result, we are going to use a vanilla instance as our basis for git comparison, and your current &amp;quot;&lt;code&gt;deployed&lt;/code&gt;&amp;quot; instance with your code installed in the filesystem.&lt;/p&gt;
&lt;p&gt;In your vanilla instance, you will follow the steps from our &lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt; and have git init and commit.&lt;/p&gt;
&lt;p&gt;Once you have that in place, (&lt;code&gt;git status&lt;/code&gt; should return empty results), you are good to go on copying all the files from your&amp;nbsp;&lt;span&gt;&lt;code&gt;deployed&lt;/code&gt;&amp;nbsp;&lt;/span&gt;instance to the&amp;nbsp;vanilla&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sh-3.2$ cp -rf /path/to/current/sugar/* /path/to/vanila/sugar/&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;* it is important to have the exact same version of Sugar, otherwise, you&amp;#39;ll have &amp;quot;noise&amp;quot; in the vendors folder and other files that aren&amp;#39;t necessarily your custom code but Sugar release-related files and those can be ignored if found.&lt;/p&gt;
&lt;p&gt;After it has been copied over, execute&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;git status&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;commands to get your customization inventory:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;sh-3.2$ git status
On branch main
Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)
        modules/FD_SignupFraudDetection/
        modules/FD_TransactionFraudDetect/

nothing added to commit but untracked files present (use &amp;quot;git add&amp;quot; to track)
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Prepare your Rector config&lt;/h3&gt;
&lt;p&gt;Copy the paths, and paste them into the rector.php config file that was generated in the previous step, replacing the default paths in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;$rectorConfig-&amp;gt;paths([&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;array like this (you can ignore some of the files, like&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*ext.php&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*orderMapping.php&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;* Please, notice the &amp;#39;/&amp;#39; after&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;constant usage. It is required as&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;does not have a trailing slash.&lt;/p&gt;
&lt;p&gt;Modify the rector.php config file to upgrade the code to the newest supported PHP version (in our case, 8.2):&lt;/p&gt;
&lt;p&gt;Remove/Comment&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// register a single rule
$rectorConfig-&amp;gt;rule(InlineConstructorDefaultToPropertyRector::class);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Add the following rules:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;sets([
    LevelSetList::UP_TO_PHP_82,
    SetList::PHP_82,
]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The following rules should be skipped to prevent known issues with Sugar.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example&lt;/h3&gt;
&lt;p&gt;By following those steps, you should have a rector.php similar to this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);

    $rectorConfig-&amp;gt;sets([
        LevelSetList::UP_TO_PHP_82,
        SetList::PHP_82,
    ]);

    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1gudgk28f0"&gt;You can move on to the&amp;nbsp;Execution Phase:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/836/executing-rector"&gt;Execute Rector&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Prepare Rector for Customizations</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations/revision/4</link><pubDate>Wed, 19 Apr 2023 19:43:13 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:0c3c010e-3789-4bb8-8641-fa07752f8e5f</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations#comments</comments><description>Revision 4 posted to Dev Tutorials by Rafael Fernandes on 4/19/2023 7:43:13 PM&lt;br /&gt;
&lt;p&gt;If you are looking to make your&amp;nbsp;customizations, not packaged in an MLP,&amp;nbsp;compatible with different versions of PHP, this guide is for you.&lt;/p&gt;
&lt;p&gt;You will take your customization code and add to the Sugar instance&amp;nbsp;&lt;span&gt;where Rector is and git has been initialized.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You need to have a inventory of your assets&amp;nbsp;to create your git/rector config.&lt;/p&gt;
&lt;h3 id="mcetoc_1guaf95jk0"&gt;Prerequisites:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customization Assets Inventory (file path of your assets)&lt;/li&gt;
&lt;li&gt;A vanila instance if you don&amp;#39;t have an inventory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1guafg2ff1"&gt;Create your Customization Inventory&lt;/h3&gt;
&lt;p&gt;If you already have&amp;nbsp;your customization inventory, great! you can skip this section.&lt;/p&gt;
&lt;p&gt;There are a few different ways of achieving the same result, we are going to use a vanilla instance as our basis for git comparison, and your current &amp;quot;&lt;code&gt;deployed&lt;/code&gt;&amp;quot; instance with your code installed in the filesystem.&lt;/p&gt;
&lt;p&gt;In your vanilla instance, you will follow the steps from our &lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt; and have git init and commit.&lt;/p&gt;
&lt;p&gt;Once you have that in place, (&lt;code&gt;git status&lt;/code&gt; should return empty results), you are good to go on copying all the files from your&amp;nbsp;&lt;span&gt;&lt;code&gt;deployed&lt;/code&gt;&amp;nbsp;&lt;/span&gt;instance to the&amp;nbsp;vanilla&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sh-3.2$ cp -rf /path/to/current/sugar/* /path/to/vanila/sugar/&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;* it is important to have the exact same version of Sugar, otherwise, you&amp;#39;ll have &amp;quot;noise&amp;quot; in the vendors folder and other files that aren&amp;#39;t necessarily your custom code but Sugar release-related files and those can be ignored if found.&lt;/p&gt;
&lt;p&gt;After it has been copied over, execute&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;git status&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;commands to get your customization inventory:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;sh-3.2$ git status
On branch main
Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)
        modules/FD_SignupFraudDetection/
        modules/FD_TransactionFraudDetect/

nothing added to commit but untracked files present (use &amp;quot;git add&amp;quot; to track)
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Prepare your Rector config&lt;/h3&gt;
&lt;p&gt;Copy the paths, and paste them into the rector.php config file that was generated in the previous step, replacing the default paths in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;$rectorConfig-&amp;gt;paths([&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;array like this (you can ignore some of the files, like&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*ext.php&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*orderMapping.php&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;* Please, notice the &amp;#39;/&amp;#39; after&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;constant usage. It is required as&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;does not have a trailing slash.&lt;/p&gt;
&lt;p&gt;Modify the rector.php config file to upgrade the code to the newest supported PHP version (in our case, 8.2):&lt;/p&gt;
&lt;p&gt;Replace&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// register a single rule
$rectorConfig-&amp;gt;rule(InlineConstructorDefaultToPropertyRector::class);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;With&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;phpstanConfig(__DIR__ . &amp;#39;/stan.neon&amp;#39;);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Add the following rules:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;sets([
    LevelSetList::UP_TO_PHP_82,
    SetList::PHP_82,
]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The following rules should be skipped to prevent known issues with Sugar.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example&lt;/h3&gt;
&lt;p&gt;By following those steps, you should have a rector.php similar to this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);

    $rectorConfig-&amp;gt;phpstanConfig(__DIR__ . &amp;#39;/stan.neon&amp;#39;);

    $rectorConfig-&amp;gt;sets([
        LevelSetList::UP_TO_PHP_82,
        SetList::PHP_82,
    ]);

    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1gudgk28f0"&gt;You can move on to the&amp;nbsp;Execution Phase:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/836/executing-rector"&gt;Execute Rector&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Prepare Rector for Customizations</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations/revision/3</link><pubDate>Wed, 19 Apr 2023 19:14:20 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:0c3c010e-3789-4bb8-8641-fa07752f8e5f</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations#comments</comments><description>Revision 3 posted to Dev Tutorials by Rafael Fernandes on 4/19/2023 7:14:20 PM&lt;br /&gt;
&lt;p&gt;If you are looking to make your&amp;nbsp;customizations, not packaged in an MLP,&amp;nbsp;compatible with different versions of PHP, this guide is for you.&lt;/p&gt;
&lt;p&gt;You will take your customization code and add to the Sugar instance&amp;nbsp;&lt;span&gt;where Rector is and git has been initialized.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You need to have a inventory of your assets&amp;nbsp;to create your git/rector config.&lt;/p&gt;
&lt;h3 id="mcetoc_1guaf95jk0"&gt;Prerequisites:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customization Assets Inventory (file path of your assets)&lt;/li&gt;
&lt;li&gt;A vanila instance if you don&amp;#39;t have an inventory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1guafg2ff1"&gt;Create your Customization Inventory&lt;/h3&gt;
&lt;p&gt;If you already have&amp;nbsp;your customization inventory, great! you can skip this section.&lt;/p&gt;
&lt;p&gt;There are a few different ways of achieving the same result, we are going to use a vanilla instance as our basis for git comparison, and your current &amp;quot;&lt;code&gt;deployed&lt;/code&gt;&amp;quot; instance with your code installed in the filesystem.&lt;/p&gt;
&lt;p&gt;In your vanilla instance, you will follow the steps from our &lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt; and have git init and commit.&lt;/p&gt;
&lt;p&gt;Once you have that in place, (&lt;code&gt;git status&lt;/code&gt; should return empty results), you are good to go on copying all the files from your&amp;nbsp;&lt;span&gt;&lt;code&gt;deployed&lt;/code&gt;&amp;nbsp;&lt;/span&gt;instance to the&amp;nbsp;vanilla&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;sh-3.2$ cp -rf /path/to/current/sugar/* /path/to/vanila/sugar/&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;* it is important to have the exact same version of Sugar, otherwise, you&amp;#39;ll have &amp;quot;noise&amp;quot; in the vendors folder and other files that aren&amp;#39;t necessarily your custom code but Sugar release-related files and those can be ignored if found.&lt;/p&gt;
&lt;p&gt;After it has been copied over, execute&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;git status&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;commands to get your customization inventory:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;sh-3.2$ git status
On branch main
Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)
        modules/FD_SignupFraudDetection/
        modules/FD_TransactionFraudDetect/

nothing added to commit but untracked files present (use &amp;quot;git add&amp;quot; to track)
&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Prepare your Rector config&lt;/h3&gt;
&lt;p&gt;Copy the paths, and paste them into the rector.php config file that was generated in the previous step, replacing the default paths in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;$rectorConfig-&amp;gt;paths([&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;array like this (you can ignore some of the files, like&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*ext.php&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*orderMapping.php&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;* Please, notice the &amp;#39;/&amp;#39; after&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;constant usage. It is required as&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;does not have a trailing slash.&lt;/p&gt;
&lt;p&gt;Modify the rector.php config file to upgrade the code to the newest supported PHP version (in our case, 8.2):&lt;/p&gt;
&lt;p&gt;Replace&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// register a single rule
$rectorConfig-&amp;gt;rule(InlineConstructorDefaultToPropertyRector::class);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;With&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;phpstanConfig(__DIR__ . &amp;#39;/stan.neon&amp;#39;);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Add the following rules:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;sets([
    LevelSetList::UP_TO_PHP_82,
    SetList::PHP_82,
]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The following rules should be skipped to prevent known issues with Sugar.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example&lt;/h3&gt;
&lt;p&gt;By following those steps, you should have a rector.php similar to this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/modules/FD_SignupFraudDetection/&amp;#39;,
        __DIR__ . &amp;#39;/modules/FD_TransactionFraudDetect/&amp;#39;,
    ]);

    $rectorConfig-&amp;gt;phpstanConfig(__DIR__ . &amp;#39;/stan.neon&amp;#39;);

    $rectorConfig-&amp;gt;sets([
        LevelSetList::UP_TO_PHP_82,
        SetList::PHP_82,
    ]);

    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Prepare Rector for Customizations</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations/revision/2</link><pubDate>Wed, 19 Apr 2023 14:54:41 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:0c3c010e-3789-4bb8-8641-fa07752f8e5f</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations#comments</comments><description>Revision 2 posted to Dev Tutorials by Rafael Fernandes on 4/19/2023 2:54:41 PM&lt;br /&gt;
&lt;p&gt;If you are looking to make your&amp;nbsp;customizations, not packaged in an MLP,&amp;nbsp;compatible with different versions of PHP, this guide is for you.&lt;/p&gt;
&lt;p&gt;You will take your customization code and add to the Sugar instance&amp;nbsp;&lt;span&gt;where Rector is and git has been initialized.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You need to have a inventory of your assets&amp;nbsp;to create your git/rector config.&lt;/p&gt;
&lt;h3 id="mcetoc_1guaf95jk0"&gt;Prerequisites:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customization Assets Inventory (file path of your assets)&lt;/li&gt;
&lt;li&gt;A vanila instance if you don&amp;#39;t have an inventory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1guafg2ff1"&gt;Create your Customization Inventory&lt;/h3&gt;
&lt;p&gt;If you already have&amp;nbsp;your customization inventory, great! you can skip this section.&lt;/p&gt;
&lt;p&gt;There are few different ways of achieving the same result, we are going to use a vanila instance as our basis for git comparison and your current &amp;quot;&lt;code&gt;deployed&lt;/code&gt;&amp;quot; instance with your code installed in the filesystem.&lt;/p&gt;
&lt;p&gt;In your vanila instance, you will follow the steps from our &lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt; and have git init and commit.&lt;/p&gt;
&lt;p&gt;Once you have that in place, (&lt;code&gt;git status&lt;/code&gt; should return empty results), you are good to go on copying all the files from your&amp;nbsp;&lt;span&gt;&lt;code&gt;deployed&lt;/code&gt;&amp;nbsp;&lt;/span&gt;instance to the&amp;nbsp;vanila&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;* it is important to have the exact same version of Sugar, otherwise you&amp;#39;ll have &amp;quot;noise&amp;quot; in the vendors folder and other files that aren&amp;#39;t necessarily your custom code but Sugar release related files and those can be ignored if found.&lt;/p&gt;
&lt;p&gt;After it has been installed, execute&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;git status&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;commands to see which files were updated/added by Sugar:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;sh-3.2$ git status
On branch main
Changes not staged for commit:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to update what will be committed)
  (use &amp;quot;git restore &amp;lt;file&amp;gt;...&amp;quot; to discard changes in working directory)
        modified:   config_override.php
        modified:   custom/application/Ext/Include/modules.ext.php

Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)
        custom/Extension/application/Ext/Include/xxxx.php
        custom/Extension/application/Ext/Include/orderMapping.php
        custom/modules/ActivityStream/
        custom/modules/Forecasts/Ext/clients/
        custom/modules/pmse_Project/

no changes added to commit (use &amp;quot;git add&amp;quot; and/or &amp;quot;git commit -a&amp;quot;)&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Prepare your Rector config&lt;/h3&gt;
&lt;p&gt;Copy the paths, and paste them into the rector.php config file that was generated in the previous step, replacing the default paths in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;$rectorConfig-&amp;gt;paths([&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;array like this (you can ignore some of the files, like&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*ext.php&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*orderMapping.php&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/custom/Extension/application/Ext/Include/BuildingBlock_HelloWorldDashlet.php&amp;#39;,
        __DIR__ . &amp;#39;/custom/clients/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/ActivityStream/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/Forecasts/Ext/clients/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/pmse_Project/&amp;#39;,
    ]);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;* Please, notice the &amp;#39;/&amp;#39; after&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;constant usage. It is required as&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;does not have a trailing slash.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Modify the rector.php config file to upgrade the code to the newest supported PHP version (in our case, 8.2):&lt;/p&gt;
&lt;p&gt;Replace&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// register a single rule
$rectorConfig-&amp;gt;rule(InlineConstructorDefaultToPropertyRector::class);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;With&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;phpstanConfig(__DIR__ . &amp;#39;/stan.neon&amp;#39;);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Add the following rules:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;sets([
    LevelSetList::UP_TO_PHP_82,
    SetList::PHP_82,
]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The following rules should be skipped to prevent known issues with Sugar.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example&lt;/h3&gt;
&lt;p&gt;By following those steps, you should have a rector.php similar to this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/custom/Extension/application/Ext/Include/BuildingBlock_HelloWorldDashlet.php&amp;#39;,
        __DIR__ . &amp;#39;/custom/clients/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/ActivityStream/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/Forecasts/Ext/clients/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/pmse_Project/&amp;#39;,
    ]);

    $rectorConfig-&amp;gt;phpstanConfig(__DIR__ . &amp;#39;/stan.neon&amp;#39;);

    $rectorConfig-&amp;gt;sets([
        LevelSetList::UP_TO_PHP_82,
        SetList::PHP_82,
    ]);

    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1guavo72a0"&gt;&lt;/h2&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Prepare Rector for Customizations</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations/revision/1</link><pubDate>Wed, 19 Apr 2023 13:32:46 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:0c3c010e-3789-4bb8-8641-fa07752f8e5f</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/837/prepare-rector-for-customizations#comments</comments><description>Revision 1 posted to Dev Tutorials by Rafael Fernandes on 4/19/2023 1:32:46 PM&lt;br /&gt;
&lt;h2 id="mcetoc_1gtthv2b41"&gt;Prepare Rector for Customizations&lt;/h2&gt;
&lt;p&gt;If you are looking to make your&amp;nbsp;customizations, not packaged in an MLP,&amp;nbsp;compatible with different versions of PHP, this guide is for you.&lt;/p&gt;
&lt;p&gt;You will take your customization code and add to the Sugar instance&amp;nbsp;&lt;span&gt;where Rector is and git has been initialized.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You need to have a inventory of your assets&amp;nbsp;to create your git/rector config.&lt;/p&gt;
&lt;h3 id="mcetoc_1guaf95jk0"&gt;Prerequisites:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customization Assets Inventory (file path of your assets)&lt;/li&gt;
&lt;li&gt;A vanila instance if you don&amp;#39;t have an inventory&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1guafg2ff1"&gt;Create your Customization Inventory&lt;/h3&gt;
&lt;p&gt;If you already have&amp;nbsp;your customization inventory, great! you can skip this section.&lt;/p&gt;
&lt;p&gt;There are few different ways of achieving the same result, we are going to use a vanila instance as our basis for git comparison and your current &amp;quot;&lt;code&gt;deployed&lt;/code&gt;&amp;quot; instance with your code installed in the filesystem.&lt;/p&gt;
&lt;p&gt;In your vanila instance, you will follow the steps from our &lt;a href="/dev-club/w/dev-tutorials/828/rector-basic-setup"&gt;Basic Setup&lt;/a&gt; and have git init and commit.&lt;/p&gt;
&lt;p&gt;Once you have that in place, (&lt;code&gt;git status&lt;/code&gt; should return empty results), you are good to go on copying all the files from your&amp;nbsp;&lt;span&gt;&lt;code&gt;deployed&lt;/code&gt;&amp;nbsp;&lt;/span&gt;instance to the&amp;nbsp;vanila&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;* it is important to have the exact same version of Sugar, otherwise you&amp;#39;ll have &amp;quot;noise&amp;quot; in the vendors folder and other files that aren&amp;#39;t necessarily your custom code but Sugar release related files and those can be ignored if found.&lt;/p&gt;
&lt;p&gt;After it has been installed, execute&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;git status&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;commands to see which files were updated/added by Sugar:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;sh-3.2$ git status
On branch main
Changes not staged for commit:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to update what will be committed)
  (use &amp;quot;git restore &amp;lt;file&amp;gt;...&amp;quot; to discard changes in working directory)
        modified:   config_override.php
        modified:   custom/application/Ext/Include/modules.ext.php

Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)
        custom/Extension/application/Ext/Include/xxxx.php
        custom/Extension/application/Ext/Include/orderMapping.php
        custom/modules/ActivityStream/
        custom/modules/Forecasts/Ext/clients/
        custom/modules/pmse_Project/

no changes added to commit (use &amp;quot;git add&amp;quot; and/or &amp;quot;git commit -a&amp;quot;)&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Prepare your Rector config&lt;/h3&gt;
&lt;p&gt;Copy the paths, and paste them into the rector.php config file that was generated in the previous step, replacing the default paths in&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;$rectorConfig-&amp;gt;paths([&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;array like this (you can ignore some of the files, like&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*ext.php&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;*orderMapping.php&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/custom/Extension/application/Ext/Include/BuildingBlock_HelloWorldDashlet.php&amp;#39;,
        __DIR__ . &amp;#39;/custom/clients/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/ActivityStream/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/Forecasts/Ext/clients/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/pmse_Project/&amp;#39;,
    ]);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;* Please, notice the &amp;#39;/&amp;#39; after&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;constant usage. It is required as&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code class="code css-z5oxh7"&gt;__DIR__&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;does not have a trailing slash.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Modify the rector.php config file to upgrade the code to the newest supported PHP version (in our case, 8.2):&lt;/p&gt;
&lt;p&gt;Replace&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;// register a single rule
$rectorConfig-&amp;gt;rule(InlineConstructorDefaultToPropertyRector::class);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;With&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;phpstanConfig(__DIR__ . &amp;#39;/stan.neon&amp;#39;);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Add the following rules:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;$rectorConfig-&amp;gt;sets([
    LevelSetList::UP_TO_PHP_82,
    SetList::PHP_82,
]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The following rules should be skipped to prevent known issues with Sugar.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1guah5gi50"&gt;Full config file example&lt;/h3&gt;
&lt;p&gt;By following those steps, you should have a rector.php similar to this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig-&amp;gt;paths([
        __DIR__ . &amp;#39;/custom/Extension/application/Ext/Include/BuildingBlock_HelloWorldDashlet.php&amp;#39;,
        __DIR__ . &amp;#39;/custom/clients/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/ActivityStream/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/Forecasts/Ext/clients/&amp;#39;,
        __DIR__ . &amp;#39;/custom/modules/pmse_Project/&amp;#39;,
    ]);

    $rectorConfig-&amp;gt;phpstanConfig(__DIR__ . &amp;#39;/stan.neon&amp;#39;);

    $rectorConfig-&amp;gt;sets([
        LevelSetList::UP_TO_PHP_82,
        SetList::PHP_82,
    ]);

    $rectorConfig-&amp;gt;skip([
        \Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector::class,
        \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class,
        \Rector\Php80\Rector\FunctionLike\UnionTypesRector::class,
        \Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector::class,
        \Rector\Php80\Rector\FunctionLike\MixedTypeRector::class,
        \Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class,
        \Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector::class,
        \Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector::class,
        \Rector\Php80\Rector\NotIdentical\StrContainsRector::class,
        \Rector\Php80\Rector\Identical\StrEndsWithRector::class,
        \Rector\Php80\Rector\Identical\StrStartsWithRector::class,
        \Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector::class,
        \Rector\Php80\Rector\Switch_\ChangeSwitchToMatchRector::class,
        \Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector::class,
        \Rector\Php81\Rector\ClassConst\FinalizePublicClassConstantRector::class,
        \Rector\Php81\Rector\Array_\FirstClassCallableRector::class,
        \Rector\Php80\Rector\FuncCall\TokenGetAllToObjectRector::class,
        \Rector\Php81\Rector\ClassMethod\NewInInitializerRector::class,
        \Rector\Php80\Rector\Class_\StringableForToStringRector::class,
        \Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector::class,
        \Rector\Php54\Rector\Array_\LongArrayToShortArrayRector::class,
        \Rector\Php74\Rector\FuncCall\ArrayKeyExistsOnPropertyRector::class,
        \Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector::class,
        \Rector\Php74\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
        \Rector\Php80\Rector\FuncCall\ClassOnObjectRector::class,
        \Rector\Php80\Rector\ClassConstFetch\ClassOnThisVariableObjectRector::class,
        \Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector::class,
        \Rector\Php82\Rector\New_\FilesystemIteratorSkipDotsRector::class,
        \Rector\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector::class,
        __DIR__ . &amp;#39;/include/SugarObjects/templates/file/views/view.edit.php&amp;#39;,
    ]);
};&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1guavo72a0"&gt;&lt;/h2&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item></channel></rss>