Advertisement
ArcaniSGK507

Untitled

Mar 31st, 2025
681
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 22.84 KB | None | 0 0
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. /**************************************************************************************
  6.  *
  7.  * Catalyst PHP Framework
  8.  * PHP Version 8.3 (Required).
  9.  *
  10.  * @see https://github.com/arcanisgk/catalyst
  11.  *
  12.  * @author    Walter Nuñez (arcanisgk/original founder) <[email protected]>
  13.  * @copyright 2023 - 2024
  14.  * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  15.  * @note      This program is distributed in the hope that it will be useful
  16.  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17.  * or FITNESS FOR A PARTICULAR PURPOSE.
  18.  *
  19.  */
  20.  
  21. namespace Catalyst\Helpers\Debug;
  22.  
  23. use Catalyst\Framework\Traits\SingletonTrait;
  24.  
  25. /**************************************************************************************
  26.  * Dumper class for debugging variables
  27.  *
  28.  * @package Catalyst\Helpers\Debug;
  29.  */
  30. class Dumper
  31. {
  32.     use SingletonTrait;
  33.  
  34.     /**
  35.      * Maximum string length in output
  36.      */
  37.     private int $maxStrLength = 150;
  38.  
  39.     /**
  40.      * Maximum array/object children to show
  41.      */
  42.     private int $maxChildren = 50;
  43.  
  44.     /**
  45.      * Maximum nesting level
  46.      */
  47.     private int $maxDepth = 5;
  48.  
  49.     /**
  50.      * Counter for generating unique IDs for collapsible elements
  51.      */
  52.     private int $collapseCounter = 0;
  53.  
  54.     /**
  55.      * Counter for generating unique IDs for dump modals
  56.      */
  57.     private static int $dumpCounter = 0;
  58.  
  59.     /**
  60.      * Dump variables with formatting
  61.      *
  62.      * @param array $options Options array with 'data' containing variables to dump
  63.      * @return void
  64.      */
  65.     public static function dump(array $options): void
  66.     {
  67.         $instance = self::getInstance();
  68.         $data = $options['data'] ?? [];
  69.         $caller = $options['caller'] ?? null;
  70.  
  71.         if (empty($data)) {
  72.             return;
  73.         }
  74.  
  75.         $isHtml = !IS_CLI;
  76.  
  77.         if (!$isHtml) {
  78.             // CLI output - proceed as normal
  79.             $width = min(80, TW);
  80.  
  81.             // Display caller information if available
  82.             if ($caller) {
  83.                 $callerText = "Called from: " . $caller['file'] . " (line " . $caller['line'] . ")";
  84.                 echo str_repeat('=', $width) . PHP_EOL;
  85.                 echo "\033[1;36m" . $callerText . "\033[0m" . PHP_EOL;
  86.                 echo str_repeat('=', $width) . PHP_EOL;
  87.             }
  88.  
  89.             // Reset collapse counter for each dump call
  90.             $instance->collapseCounter = 0;
  91.  
  92.             foreach ($data as $var) {
  93.                 $instance->dumpVar($var, 'Output', $isHtml);
  94.                 echo str_repeat('-', $width) . PHP_EOL;
  95.             }
  96.  
  97.             return;
  98.         }
  99.  
  100.         // HTML output - create a modal
  101.         $dumpId = 'catalyst-dump-' . (++self::$dumpCounter);
  102.         $modalId = $dumpId . '-modal';
  103.         $btnId = $dumpId . '-btn';
  104.  
  105.         // Add CSS and JavaScript for modal functionality
  106.         echo '<style>
  107.            .' . $dumpId . '-modal {
  108.                display: none;
  109.                position: fixed;
  110.                z-index: 9999;
  111.                left: 0;
  112.                top: 0;
  113.                width: 100%;
  114.                height: 100%;
  115.                overflow: hidden;
  116.                background-color: rgba(0, 0, 0, 0.7);
  117.                backdrop-filter: blur(2px);
  118.            }
  119.            .' . $dumpId . '-modal-content {
  120.                position: relative;
  121.                background-color: #1d1e22;
  122.                margin: 30px auto;
  123.                padding: 0;
  124.                width: 90%;
  125.                max-width: 1200px;
  126.                max-height: 90vh;
  127.                border-radius: 8px;
  128.                box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
  129.                display: flex;
  130.                flex-direction: column;
  131.                overflow: hidden;
  132.            }
  133.            .' . $dumpId . '-close {
  134.                position: absolute;
  135.                top: 50%;
  136.                right: 15px;
  137.                transform: translateY(-50%);
  138.                width: 14px;
  139.                height: 14px;
  140.                background-color: #ff5f57;
  141.                border-radius: 50%;
  142.                cursor: pointer;
  143.                z-index: 1;
  144.                display: flex;
  145.                align-items: center;
  146.                justify-content: center;
  147.                box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
  148.            }
  149.            .' . $dumpId . '-close:hover::before {
  150.                content: "×";
  151.                font-size: 12px;
  152.                color: rgba(0, 0, 0, 0.5);
  153.                line-height: 1;
  154.            }
  155.            .' . $dumpId . '-btn {
  156.                position: fixed;
  157.                bottom: 20px;
  158.                left: 20px;
  159.                background-color: #2d2d30;
  160.                color: #80deea;
  161.                border: none;
  162.                border-radius: 50%;
  163.                width: 50px;
  164.                height: 50px;
  165.                font-size: 24px;
  166.                cursor: pointer;
  167.                box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
  168.                z-index: 9998;
  169.                display: flex;
  170.                align-items: center;
  171.                justify-content: center;
  172.                transition: all 0.2s ease;
  173.            }
  174.            .' . $dumpId . '-btn:hover {
  175.                background-color: #3d3d40;
  176.                transform: scale(1.05);
  177.            }
  178.            .' . $dumpId . '-btn-badge {
  179.                position: absolute;
  180.                top: -5px;
  181.                right: -5px;
  182.                background-color: #ef5350;
  183.                color: white;
  184.                border-radius: 50%;
  185.                width: 20px;
  186.                height: 20px;
  187.                font-size: 12px;
  188.                display: flex;
  189.                align-items: center;
  190.                justify-content: center;
  191.            }
  192.            .' . $dumpId . '-modal-header {
  193.                padding: 15px 40px 15px 15px;
  194.                background-color: #2d2d30;
  195.                border-bottom: 1px solid #3d3d40;
  196.                border-radius: 8px 8px 0 0;
  197.                flex-shrink: 0;
  198.                position: relative;
  199.            }
  200.            .' . $dumpId . '-modal-body {
  201.                padding: 15px;
  202.                overflow: auto;
  203.                max-height: calc(90vh - 60px);
  204.            }
  205.        </style>';
  206.  
  207.         echo '<script>
  208.            // Function to toggle collapsible sections
  209.            function toggleCollapse(id) {
  210.                const content = document.getElementById("content-" + id);
  211.                const chevron = document.getElementById("chevron-" + id);
  212.  
  213.                if (content.style.display === "none") {
  214.                    content.style.display = "block";
  215.                    chevron.innerHTML = "&#9660;"; // Down chevron
  216.                    chevron.title = "Collapse";
  217.                } else {
  218.                    content.style.display = "none";
  219.                    chevron.innerHTML = "&#9658;"; // Right chevron
  220.                    chevron.title = "Expand";
  221.                }
  222.            }
  223.  
  224.            // Function to toggle modal visibility
  225.            function toggleModal' . self::$dumpCounter . '() {
  226.                const modal = document.getElementById("' . $modalId . '");
  227.                if (modal.style.display === "block") {
  228.                    modal.style.display = "none";
  229.                } else {
  230.                    modal.style.display = "block";
  231.                }
  232.            }
  233.  
  234.            // Close modal when clicking outside of it
  235.            document.addEventListener("DOMContentLoaded", function() {
  236.                const modal = document.getElementById("' . $modalId . '");
  237.                window.addEventListener("click", function(event) {
  238.                    if (event.target === modal) {
  239.                        modal.style.display = "none";
  240.                    }
  241.                });
  242.            });
  243.        </script>';
  244.  
  245.         // Create the modal structure
  246.         echo '<div id="' . $modalId . '" class="' . $dumpId . '-modal">
  247.            <div class="' . $dumpId . '-modal-content">
  248.                <div class="' . $dumpId . '-modal-header">
  249.                    <span class="' . $dumpId . '-close" onclick="toggleModal' . self::$dumpCounter . '()"></span>';
  250.  
  251.         // Display caller information in modal header if available
  252.         if ($caller) {
  253.             $callerText = "Called from: " . $caller['file'] . " (line " . $caller['line'] . ")";
  254.             echo '<span style="color:#80deea;font-weight:bold;">' . htmlspecialchars($callerText) . '</span>';
  255.         } else {
  256.             echo '<span style="color:#80deea;font-weight:bold;">Debug Information</span>';
  257.         }
  258.  
  259.         echo '</div>
  260.                <div class="' . $dumpId . '-modal-body">
  261.                    <pre style="background-color:#1d1e22; color:#e6e6e6; padding:0; margin:0; font-family:monospace;">';
  262.  
  263.         // Reset collapse counter for each dump call
  264.         $instance->collapseCounter = 0;
  265.  
  266.         foreach ($data as $var) {
  267.             $instance->dumpVar($var, 'Output', $isHtml);
  268.             echo '<hr style="border:1px dashed #505050; margin:10px 0;">';
  269.         }
  270.  
  271.         echo '</pre>
  272.                </div>
  273.            </div>
  274.        </div>';
  275.  
  276.         // Create the floating button
  277.         echo '<button id="' . $btnId . '" class="' . $dumpId . '-btn" onclick="toggleModal' . self::$dumpCounter . '()" title="Show Debug Information">
  278.            <span style="font-size:20px;">&#128270;</span>
  279.            <span class="' . $dumpId . '-btn-badge">' . count($data) . '</span>
  280.        </button>';
  281.     }
  282.  
  283.     /**
  284.      * Format and output the variable
  285.      *
  286.      * @param mixed $var Variable to dump
  287.      * @param string $label Variable label
  288.      * @param bool $isHtml Whether to format for HTML output
  289.      * @param int $depth Current depth level
  290.      * @return void
  291.      */
  292.     private function dumpVar(mixed $var, string $label = '', bool $isHtml = true, int $depth = 0): void
  293.     {
  294.         $indent = str_repeat('    ', $depth);
  295.         $type = gettype($var);
  296.  
  297.         $valueDisplay = match ($type) {
  298.             'string' => $this->formatString($var, $isHtml),
  299.             'integer', 'double' => $this->formatNumber($var, $isHtml),
  300.             'boolean' => $this->formatBoolean($var, $isHtml),
  301.             'NULL' => $this->formatNull($isHtml),
  302.             'array' => $this->formatArray($var, $isHtml, $depth),
  303.             'object' => $this->formatObject($var, $isHtml, $depth),
  304.             'resource' => $this->formatResource($var, $isHtml),
  305.             default => "($type)"
  306.         };
  307.  
  308.         $typeColor = $this->getTypeColor($type, $isHtml);
  309.         $labelOutput = $label ? $this->colorText($label . ' ', 'label', $isHtml) : '';
  310.  
  311.         echo $indent . $labelOutput . $this->colorText("($type)", $typeColor, $isHtml) . ' ' . $valueDisplay . PHP_EOL;
  312.     }
  313.  
  314.     /**
  315.      * Format string for output
  316.      *
  317.      * @param string $var
  318.      * @param bool $isHtml
  319.      * @return string
  320.      */
  321.     private function formatString(string $var, bool $isHtml): string
  322.     {
  323.         $length = strlen($var);
  324.  
  325.         // Handle multiline strings
  326.         if (str_contains($var, "\n")) {
  327.             $lines = explode("\n", $var);
  328.             $firstLine = htmlspecialchars($lines[0], ENT_QUOTES | ENT_HTML5);
  329.             $result = $this->colorText('"' . $firstLine, 'string', $isHtml);
  330.  
  331.             // Indent and append remaining lines
  332.             for ($i = 1; $i < count($lines); $i++) {
  333.                 $line = htmlspecialchars($lines[$i], ENT_QUOTES | ENT_HTML5);
  334.                 $result .= "\n" . str_repeat(' ', 8) . $this->colorText($line, 'string', $isHtml);
  335.             }
  336.  
  337.             $result .= $this->colorText('"', 'string', $isHtml) .
  338.                 $this->colorText(" (length=" . $length . ", multiline)", 'meta', $isHtml);
  339.  
  340.             return $result;
  341.         }
  342.  
  343.         // Handle regular strings
  344.         $var = htmlspecialchars($var, ENT_QUOTES | ENT_HTML5);
  345.  
  346.         if ($length > $this->maxStrLength) {
  347.             $var = substr($var, 0, $this->maxStrLength) . '...';
  348.         }
  349.  
  350.         return $this->colorText('"' . $var . '"', 'string', $isHtml) .
  351.             $this->colorText(" (length=" . $length . ")", 'meta', $isHtml);
  352.     }
  353.  
  354.     /**
  355.      * Format numeric value for output
  356.      *
  357.      * @param int|float $var
  358.      * @param bool $isHtml
  359.      * @return string
  360.      */
  361.     private function formatNumber(int|float $var, bool $isHtml): string
  362.     {
  363.         return $this->colorText((string)$var, 'number', $isHtml);
  364.     }
  365.  
  366.     /**
  367.      * Format boolean for output
  368.      *
  369.      * @param bool $var
  370.      * @param bool $isHtml
  371.      * @return string
  372.      */
  373.     private function formatBoolean(bool $var, bool $isHtml): string
  374.     {
  375.         return $this->colorText($var ? 'true' : 'false', 'boolean', $isHtml);
  376.     }
  377.  
  378.     /**
  379.      * Format null for output
  380.      *
  381.      * @param bool $isHtml
  382.      * @return string
  383.      */
  384.     private function formatNull(bool $isHtml): string
  385.     {
  386.         return $this->colorText('null', 'null', $isHtml);
  387.     }
  388.  
  389.     /**
  390.      * Create a collapsible section with chevron toggle
  391.      *
  392.      * @param string $header Header content
  393.      * @param string $content Content to be collapsed/expanded
  394.      * @param bool $isHtml Whether to format for HTML output
  395.      * @param bool $initiallyExpanded Whether the content should be initially expanded
  396.      * @param int $depth Current nesting depth for indentation
  397.      * @return string Formatted output with collapsible functionality
  398.      */
  399.     private function createCollapsible(string $header, string $content, bool $isHtml, bool $initiallyExpanded = true, int $depth = 0): string
  400.     {
  401.         $indent = str_repeat('    ', $depth);
  402.  
  403.         if (!$isHtml) {
  404.             // For CLI, just return the content without collapsible functionality
  405.             return $header . " {" . PHP_EOL . $content . PHP_EOL . $indent . "}";
  406.         }
  407.  
  408.         // Generate a unique ID for this collapsible section
  409.         $id = ++$this->collapseCounter;
  410.  
  411.         // Determine initial state
  412.         $displayStyle = $initiallyExpanded ? 'block' : 'none';
  413.         $chevronChar = $initiallyExpanded ? '&#9660;' : '&#9658;';
  414.         $chevronTitle = $initiallyExpanded ? 'Collapse' : 'Expand';
  415.  
  416.         // Create the collapsible HTML structure
  417.         $result = '<span style="cursor:pointer;" onclick="toggleCollapse(' . $id . ')">';
  418.         $result .= '<span id="chevron-' . $id . '" title="' . $chevronTitle . '" style="display:inline-block;width:15px;text-align:center;color:#9e9e9e;">' . $chevronChar . '</span>';
  419.         $result .= $header . ' {</span>' . PHP_EOL;
  420.         $result .= '<div id="content-' . $id . '" style="display:' . $displayStyle . ';">' . $content . '</div>';
  421.         $result .= $indent . '}';
  422.  
  423.         return $result;
  424.     }
  425.  
  426.     /**
  427.      * Format array for output
  428.      *
  429.      * @param array $var
  430.      * @param bool $isHtml
  431.      * @param int $depth
  432.      * @return string
  433.      */
  434.     private function formatArray(array $var, bool $isHtml, int $depth): string
  435.     {
  436.         $count = count($var);
  437.         if ($depth >= $this->maxDepth) {
  438.             return $this->colorText("Array", 'array', $isHtml) .
  439.                 $this->colorText(" (items=" . $count . ")", 'meta', $isHtml) .
  440.                 $this->colorText(" [MAX DEPTH REACHED]", 'error', $isHtml);
  441.         }
  442.  
  443.         $header = $this->colorText("Array", 'array', $isHtml) .
  444.             $this->colorText(" (items=" . $count . ")", 'meta', $isHtml);
  445.  
  446.         // If array is empty, don't make it collapsible
  447.         if ($count === 0) {
  448.             return $header . " {}";
  449.         }
  450.  
  451.         $contentBuffer = '';
  452.         $i = 0;
  453.         foreach ($var as $key => $value) {
  454.             if ($i >= $this->maxChildren) {
  455.                 $indent = str_repeat('    ', $depth + 1);
  456.                 $contentBuffer .= $indent . $this->colorText("... +" . ($count - $this->maxChildren) . " more items", 'meta', $isHtml) . PHP_EOL;
  457.                 break;
  458.             }
  459.  
  460.             $keyDisplay = is_string($key) ?
  461.                 $this->colorText("\"$key\"", 'key', $isHtml) :
  462.                 $this->colorText((string)$key, 'key', $isHtml);
  463.  
  464.             $contentBuffer .= str_repeat('    ', $depth + 1) .
  465.                 "[" . $keyDisplay . "] => ";
  466.  
  467.             // Capture output from recursive call
  468.             ob_start();
  469.             $this->dumpVar($value, '', $isHtml, $depth + 1);
  470.             $contentBuffer .= trim(ob_get_clean());
  471.             $contentBuffer .= PHP_EOL;
  472.  
  473.             $i++;
  474.         }
  475.  
  476.         // Make the array collapsible
  477.         return $this->createCollapsible($header, $contentBuffer, $isHtml, true, $depth);
  478.     }
  479.  
  480.     /**
  481.      * Format object for output
  482.      *
  483.      * @param object $var
  484.      * @param bool $isHtml
  485.      * @param int $depth
  486.      * @return string
  487.      */
  488.     private function formatObject(object $var, bool $isHtml, int $depth): string
  489.     {
  490.         $class = get_class($var);
  491.         $props = (array)$var;
  492.         $count = count($props);
  493.  
  494.         if ($depth >= $this->maxDepth) {
  495.             return $this->colorText($class, 'object', $isHtml) .
  496.                 $this->colorText(" (properties=" . $count . ")", 'meta', $isHtml) .
  497.                 $this->colorText(" [MAX DEPTH REACHED]", 'error', $isHtml);
  498.         }
  499.  
  500.         $header = $this->colorText($class, 'object', $isHtml) .
  501.             $this->colorText(" (properties=" . $count . ")", 'meta', $isHtml);
  502.  
  503.         // If object has no properties, don't make it collapsible
  504.         if ($count === 0) {
  505.             return $header . " {}";
  506.         }
  507.  
  508.         $contentBuffer = '';
  509.         $i = 0;
  510.         foreach ($props as $key => $value) {
  511.             if ($i >= $this->maxChildren) {
  512.                 $indent = str_repeat('    ', $depth + 1);
  513.                 $contentBuffer .= $indent . $this->colorText("... +" . ($count - $this->maxChildren) . " more properties", 'meta', $isHtml) . PHP_EOL;
  514.                 break;
  515.             }
  516.  
  517.             // Handle property name with potential visibility indicator
  518.             $keyString = (string)$key;
  519.             $keyParts = explode("\0", $keyString);
  520.             $propName = end($keyParts);
  521.             $visibility = 'public';
  522.  
  523.             if (count($keyParts) > 1) {
  524.                 $visibility = $keyParts[1] === '*' ? 'protected' : 'private';
  525.             }
  526.  
  527.             $visColor = match ($visibility) {
  528.                 'private' => 'private',
  529.                 'protected' => 'protected',
  530.                 default => 'public'
  531.             };
  532.  
  533.             $contentBuffer .= str_repeat('    ', $depth + 1) .
  534.                 $this->colorText("[$visibility]", $visColor, $isHtml) . " " .
  535.                 $this->colorText("$propName", 'key', $isHtml) . " => ";
  536.  
  537.             // Capture output from recursive call
  538.             ob_start();
  539.             $this->dumpVar($value, '', $isHtml, $depth + 1);
  540.             $contentBuffer .= trim(ob_get_clean());
  541.             $contentBuffer .= PHP_EOL;
  542.  
  543.             $i++;
  544.         }
  545.  
  546.         // Make the object collapsible
  547.         return $this->createCollapsible($header, $contentBuffer, $isHtml, true, $depth);
  548.     }
  549.  
  550.     /**
  551.      * Format resource for output
  552.      *
  553.      * @param $var
  554.      * @param bool $isHtml
  555.      * @return string
  556.      */
  557.     private function formatResource($var, bool $isHtml): string
  558.     {
  559.         $type = get_resource_type($var);
  560.         return $this->colorText("resource($type)", 'resource', $isHtml) .
  561.             $this->colorText(" id=" . (int)$var, 'meta', $isHtml);
  562.     }
  563.  
  564.     /**
  565.      * Get color associated with type
  566.      *
  567.      * @param string $type
  568.      * @param bool $isHtml
  569.      * @return string
  570.      */
  571.     private function getTypeColor(string $type, bool $isHtml): string
  572.     {
  573.         return match ($type) {
  574.             'string' => 'string',
  575.             'integer', 'double' => 'number',
  576.             'boolean' => 'boolean',
  577.             'NULL' => 'null',
  578.             'array' => 'array',
  579.             'object' => 'object',
  580.             'resource' => 'resource',
  581.             default => 'default'
  582.         };
  583.     }
  584.  
  585.     /**
  586.      * Apply color to text based on context
  587.      *
  588.      * @param string $text
  589.      * @param string $context
  590.      * @param bool $isHtml
  591.      * @return string
  592.      */
  593.     private function colorText(string $text, string $context, bool $isHtml): string
  594.     {
  595.         if (!$isHtml) {
  596.             // ANSI color codes for CLI
  597.             return match ($context) {
  598.                 'string' => "\033[0;32m" . $text . "\033[0m", // Green
  599.                 'number' => "\033[0;34m" . $text . "\033[0m", // Blue
  600.                 'boolean' => "\033[0;35m" . $text . "\033[0m", // Magenta
  601.                 'null' => "\033[0;31m" . $text . "\033[0m", // Red
  602.                 'array' => "\033[0;33m" . $text . "\033[0m", // Yellow
  603.                 'object' => "\033[0;36m" . $text . "\033[0m", // Cyan
  604.                 'resource' => "\033[0;95m" . $text . "\033[0m", // Light magenta
  605.                 'key' => "\033[0;33m" . $text . "\033[0m", // Yellow
  606.                 'meta' => "\033[0;90m" . $text . "\033[0m", // Dark gray
  607.                 'error' => "\033[0;91m" . $text . "\033[0m", // Light red
  608.                 'label' => "\033[1;37m" . $text . "\033[0m", // Bold white
  609.                 'public' => "\033[0;92m" . $text . "\033[0m", // Light green
  610.                 'protected' => "\033[0;93m" . $text . "\033[0m", // Light yellow
  611.                 'private' => "\033[0;91m" . $text . "\033[0m", // Light red
  612.                 'chevron' => "\033[0;90m" . $text . "\033[0m", // Dark gray
  613.                 default => $text
  614.             };
  615.         }
  616.  
  617.         // HTML colors
  618.         return match ($context) {
  619.             'string' => '<span style="color:#a5d6a7;">' . $text . '</span>',
  620.             'number' => '<span style="color:#90caf9;">' . $text . '</span>',
  621.             'boolean' => '<span style="color:#ce93d8;">' . $text . '</span>',
  622.             'null' => '<span style="color:#ef9a9a;">' . $text . '</span>',
  623.             'array' => '<span style="color:#ffcc80;">' . $text . '</span>',
  624.             'object' => '<span style="color:#80deea;">' . $text . '</span>',
  625.             'resource' => '<span style="color:#ea80fc;">' . $text . '</span>',
  626.             'key' => '<span style="color:#ffe082;">' . $text . '</span>',
  627.             'meta' => '<span style="color:#9e9e9e;">' . $text . '</span>',
  628.             'error' => '<span style="color:#ef5350;">' . $text . '</span>',
  629.             'label' => '<span style="color:#ffffff;font-weight:bold;">' . $text . '</span>',
  630.             'public' => '<span style="color:#81c784;">' . $text . '</span>',
  631.             'protected' => '<span style="color:#fff176;">' . $text . '</span>',
  632.             'private' => '<span style="color:#ef5350;">' . $text . '</span>',
  633.             'chevron' => '<span style="color:#9e9e9e;">' . $text . '</span>',
  634.             default => $text
  635.         };
  636.     }
  637. }
  638.  
  639.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement