diff --git a/src/File/PicoDownloadFile.php b/src/File/PicoDownloadFile.php new file mode 100644 index 00000000..d59eb837 --- /dev/null +++ b/src/File/PicoDownloadFile.php @@ -0,0 +1,181 @@ +filepath = $filepath; + $this->filename = $filename ?: basename($filepath); // Use basename if no filename provided + } + + /** + * Initiates the download of the file with support for partial content (range requests). + * + * Handles the following: + * - Verifies the file exists at the specified path. + * - Supports byte range requests for resuming downloads. + * - Sends appropriate HTTP headers for file transfer. + * - Streams the file to the client in chunks (8 KB by default). + * + * @param bool $exit Whether to terminate the script after sending the file. Default is `false`. + * + * @return bool Returns `true` if the entire file was successfully sent, `false` if only part of the file was sent. + */ + public function download($exit = false) //NOSONAR + { + if (!$this->fileExists()) { + $this->sendError(404, "File not found."); + return false; + } + + $fileSize = filesize($this->filepath); + list($start, $end) = $this->getRange($fileSize); + + if ($this->isInvalidRange($start, $end, $fileSize)) { + $this->sendError(416, "Range Not Satisfiable", $fileSize); + return false; + } + + $this->sendHeaders($start, $end, $fileSize); + + $fp = fopen($this->filepath, 'rb'); + if ($fp === false) { + $this->sendError(500, "Failed to open file."); + return false; + } + + $this->streamFile($fp, $start, $end); + + fclose($fp); + + if ($exit) { + exit; + } + + return $end === ($fileSize - 1); // Return true if the whole file was sent + } + + /** + * Checks if the file exists. + * + * @return bool True if the file exists, false otherwise. + */ + private function fileExists() + { + return file_exists($this->filepath); + } + + /** + * Sends an error response with the given status code and message. + * + * @param int $statusCode The HTTP status code. + * @param string $message The error message. + * @param int|null $fileSize The file size to include in the Content-Range header (optional). + */ + private function sendError($statusCode, $message, $fileSize = null) + { + header("HTTP/1.1 $statusCode $message"); + if ($fileSize !== null) { + header("Content-Range: bytes 0-0/$fileSize"); + } + echo $message; + } + + /** + * Determines the byte range from the HTTP_RANGE header. + * + * @param int $fileSize The size of the file. + * @return array The start and end byte positions for the range. + */ + private function getRange($fileSize) + { + if (isset($_SERVER['HTTP_RANGE'])) { + list($range, $extra) = explode(',', $_SERVER['HTTP_RANGE'], 2); //NOSONAR + list($start, $end) = explode('-', $range); + $start = max(0, (int)$start); + $end = $end ? (int)$end : $fileSize - 1; + } else { + $start = 0; + $end = $fileSize - 1; + } + + return [$start, $end]; + } + + /** + * Checks if the byte range is valid. + * + * @param int $start The start byte. + * @param int $end The end byte. + * @param int $fileSize The total size of the file. + * @return bool True if the range is invalid. + */ + private function isInvalidRange($start, $end, $fileSize) + { + return $start > $end || $start >= $fileSize || $end >= $fileSize; + } + + /** + * Sends the appropriate HTTP headers for the download. + * + * @param int $start The start byte. + * @param int $end The end byte. + * @param int $fileSize The total size of the file. + */ + private function sendHeaders($start, $end, $fileSize) + { + header('HTTP/1.1 206 Partial Content'); + header("Content-Type: application/octet-stream"); + header("Content-Description: File Transfer"); + header("Content-Disposition: attachment; filename=\"" . $this->filename . "\""); + header("Content-Range: bytes $start-$end/$fileSize"); + header("Content-Length: " . ($end - $start + 1)); + header("Accept-Ranges: bytes"); + } + + /** + * Streams the file to the client in chunks. + * + * @param resource $fp The file pointer. + * @param int $start The start byte. + * @param int $end The end byte. + */ + private function streamFile($fp, $start, $end) + { + $bufferSize = 1024 * 8; // 8 KB buffer size + fseek($fp, $start); + while (!feof($fp) && ftell($fp) <= $end) { + echo fread($fp, $bufferSize); + flush(); + } + } +} diff --git a/src/Geometry/Area.php b/src/Geometry/Area.php index a0ffff4e..bbe1910b 100644 --- a/src/Geometry/Area.php +++ b/src/Geometry/Area.php @@ -172,12 +172,12 @@ public function getHTML() $attrs[] = 'coords="' . implode(", ", $this->getCoords($this->zoom)) . '"'; if (isset($this->href)) { - $attrs[] = 'href="' . htmlspecialchars($this->href) . '"'; + $attrs[] = 'href="' . $this->href . '"'; } if (isset($this->attributes) && is_array($this->attributes)) { foreach ($this->attributes as $key => $value) { - $attrs[] = $key . '="' . htmlspecialchars($value) . '"'; + $attrs[] = $key . '="' . $value . '"'; } } diff --git a/src/Txt.php b/src/Txt.php index 41ea42fc..d315626b 100644 --- a/src/Txt.php +++ b/src/Txt.php @@ -5,24 +5,65 @@ /** * Class Txt * - * A utility class that provides dynamic handling of static method calls. - * This class allows for flexible interaction by returning the names of - * methods that are called statically but are not explicitly defined within - * the class. It can be useful for implementing dynamic behavior or - * creating a fluent interface. + * A utility class that provides dynamic handling of static method calls and dynamic property access. + * This class allows for flexible interaction by returning the names of methods and properties + * that are called statically or accessed dynamically but are not explicitly defined within the class. + * It can be useful for implementing dynamic behavior or creating a fluent interface. */ class Txt { /** * Handles static calls to undefined methods. * - * This method returns the name of the method being called. + * This method intercepts calls to static methods that are not explicitly defined in the class + * and returns the name of the method being called. It allows for flexible handling of undefined + * static methods. * * @param string $name The name of the method being called. * @param array $arguments An array of arguments passed to the method. - * @return string|null The name of the called method, or null if no arguments are provided. + * @return string The name of the called method. */ - public static function __callStatic($name, $arguments) + public static function __callStatic($name, $arguments) //NOSONAR + { + return $name; + } + + /** + * Returns a new instance of the Txt class. + * + * This method allows you to retrieve an instance of the Txt class for non-static operations. + * This instance can be used to access dynamic properties via the __get() magic method. + * + * @return Txt A new instance of the Txt class. + */ + public static function getInstance() + { + return new self; + } + + /** + * Creates and returns a new instance of the Txt class. + * + * Similar to getInstance(), this method allows you to retrieve an instance of the Txt class + * for non-static operations, such as dynamic property access using the __get() magic method. + * + * @return Txt A new instance of the Txt class. + */ + public static function of() + { + return new self; + } + + /** + * Handles dynamic access to undefined properties. + * + * This method is invoked when an undefined property is accessed on an instance of the Txt class. + * It returns the name of the property being accessed. + * + * @param string $name The name of the property being accessed. + * @return string The name of the accessed property. + */ + public function __get($name) { return $name; } diff --git a/src/Util/PicoLocale.php b/src/Util/PicoLocale.php index 1ff9778d..1186da54 100644 --- a/src/Util/PicoLocale.php +++ b/src/Util/PicoLocale.php @@ -5,6 +5,11 @@ /** * Locale * + * The `PicoLocale` class serves as a container for a collection of predefined locale constants. + * These constants represent different locale identifiers for various countries, regions, and languages, using the format of language-region (e.g., "en_US" for English in the United States, "fr_FR" for French in France). + * + * Each constant corresponds to a specific locale, which can be used in applications to handle internationalization (i18n), localization (l10n), and formatting of data such as dates, currencies, and numbers, based on the user's regional settings. + * * @author Kamshory * @package MagicObject\Util * @link https://github.com/Planetbiru/MagicObject diff --git a/src/Util/PicoParsedown.php b/src/Util/PicoParsedown.php index ca961071..6ac9a213 100644 --- a/src/Util/PicoParsedown.php +++ b/src/Util/PicoParsedown.php @@ -15,7 +15,7 @@ # # -class PicoParsedown +class PicoParsedown //NOSONAR { /** * The current version of the parser. @@ -206,7 +206,7 @@ public function setSafeMode($safeMode) * @param array $lines The lines of text to process. * @return string The generated HTML markup. */ - protected function lines(array $lines) + protected function lines(array $lines) //NOSONAR { $CurrentBlock = null; @@ -383,13 +383,13 @@ protected function isBlockCompletable($Type) protected function blockCode($line, $block = null) { if (isset($block) && !isset($block['type']) && !isset($block['interrupted'])) { - return; + return null; } if ($line['indent'] >= 4) { $text = substr($line['body'], 4); - $block = array( + return array( 'element' => array( 'name' => 'pre', 'handler' => 'element', @@ -400,7 +400,6 @@ protected function blockCode($line, $block = null) ), ); - return $block; } } @@ -440,7 +439,25 @@ protected function blockCodeContinue($line, $block) * @param array $block The block to complete. * @return array The completed code block. */ - protected function blockCodeComplete($block) + protected function blockCodeComplete($block) //NOSONAR + { + $text = $block['element']['text']['text']; + + $block['element']['text']['text'] = $text; + + return $block; + } + + /** + * Continue processing a fenced code block. + * + * This method appends additional lines to an existing fenced code block. + * + * @param array $line The line of text to process. + * @param array $block The current fenced code block being processed. + * @return array|null The updated fenced code block or null if not applicable. + */ + protected function blockFencedCodeComplete($block) //NOSONAR { $text = $block['element']['text']['text']; @@ -460,7 +477,7 @@ protected function blockCodeComplete($block) protected function blockComment($line) { if ($this->markupEscaped || $this->safeMode) { - return; + return null; } if (isset($line['text'][3]) && $line['text'][3] === '-' && $line['text'][2] === '-' && $line['text'][1] === '!') { @@ -488,7 +505,7 @@ protected function blockComment($line) protected function blockCommentContinue($line, array $block) { if (isset($block['closed'])) { - return; + return null; } $block['markup'] .= "\n" . $line['body']; @@ -539,7 +556,7 @@ protected function blockFencedCode($line) ); } - $block = array( + return array( 'char' => $line['text'][0], 'element' => array( 'name' => 'pre', @@ -548,7 +565,6 @@ protected function blockFencedCode($line) ), ); - return $block; } } @@ -565,7 +581,7 @@ protected function blockFencedCode($line) protected function blockFencedCodeContinue($line, $block) { if (isset($block['complete'])) { - return; + return null; } if (isset($block['interrupted'])) { @@ -587,23 +603,7 @@ protected function blockFencedCodeContinue($line, $block) return $block; } - /** - * Continue processing a fenced code block. - * - * This method appends additional lines to an existing fenced code block. - * - * @param array $line The line of text to process. - * @param array $block The current fenced code block being processed. - * @return array|null The updated fenced code block or null if not applicable. - */ - protected function blockFencedCodeComplete($block) - { - $text = $block['element']['text']['text']; - - $block['element']['text']['text'] = $text; - - return $block; - } + /** * Complete the fenced code block. @@ -623,20 +623,18 @@ protected function blockHeader($line) } if ($level > 6) { - return; + return null; } $text = trim($line['text'], '# '); - $block = array( + return array( 'element' => array( 'name' => 'h' . min(6, $level), 'text' => $text, 'handler' => 'line', ), ); - - return $block; } } @@ -693,7 +691,7 @@ protected function blockList($line) * @param array $block The current list block being processed. * @return array|null The updated list block or null if not applicable. */ - protected function blockListContinue($line, array $block) + protected function blockListContinue($line, array $block) //NOSONAR { if ($block['indent'] === $line['indent'] && preg_match('/^' . $block['pattern'] . '(?:[ ]+(.*)|$)/', $line['text'], $matches)) { if (isset($block['interrupted'])) { @@ -726,7 +724,7 @@ protected function blockListContinue($line, array $block) } if (!isset($block['interrupted'])) { - $text = preg_replace('/^[ ]{0,4}/', '', $line['body']); + $text = preg_replace('/^[ ]{0,4}/', '', $line['body']); //NOSONAR $block['li']['text'][] = $text; @@ -736,7 +734,7 @@ protected function blockListContinue($line, array $block) if ($line['indent'] > 0) { $block['li']['text'][] = ''; - $text = preg_replace('/^[ ]{0,4}/', '', $line['body']); + $text = preg_replace('/^[ ]{0,4}/', '', $line['body']); //NOSONAR $block['li']['text'][] = $text; @@ -777,17 +775,17 @@ protected function blockListComplete(array $block) */ protected function blockQuote($line) { - if (preg_match('/^>[ ]?(.*)/', $line['text'], $matches)) { - $block = array( + if (preg_match('/^>[ ]?(.*)/', $line['text'], $matches)) //NOSONAR + { + return array( 'element' => array( 'name' => 'blockquote', 'handler' => 'lines', 'text' => (array) $matches[1], ), ); - - return $block; } + return null; } /** @@ -801,7 +799,8 @@ protected function blockQuote($line) */ protected function blockQuoteContinue($line, array $block) { - if ($line['text'][0] === '>' && preg_match('/^>[ ]?(.*)/', $line['text'], $matches)) { + if ($line['text'][0] === '>' && preg_match('/^>[ ]?(.*)/', $line['text'], $matches)) //NOSONAR + { if (isset($block['interrupted'])) { $block['element']['text'][] = ''; @@ -831,13 +830,12 @@ protected function blockQuoteContinue($line, array $block) protected function blockRule($line) { if (preg_match('/^([' . $line['text'][0] . '])([ ]*\1){2,}[ ]*$/', $line['text'])) { - $block = array( + return array( 'element' => array( 'name' => 'hr' ), ); - return $block; } } @@ -853,7 +851,7 @@ protected function blockRule($line) protected function blockSetextHeader($line, array $block = null) { if (!isset($block) || isset($block['type']) || isset($block['interrupted'])) { - return; + return null; } if (chop($line['text'], $line['text'][0]) === '') { @@ -871,17 +869,17 @@ protected function blockSetextHeader($line, array $block = null) * @param array $line The line of text to process. * @return array|null The constructed markup block or null if not applicable. */ - protected function blockMarkup($line) + protected function blockMarkup($line) //NOSONAR { if ($this->markupEscaped || $this->safeMode) { - return; + return null; } if (preg_match('/^<(\w[\w-]*)(?:[ ]*' . $this->regexHtmlAttribute . ')*[ ]*(\/)?>/', $line['text'], $matches)) { $element = strtolower($matches[1]); if (in_array($element, $this->textLevelElements)) { - return; + return null; } $block = array( @@ -902,7 +900,7 @@ protected function blockMarkup($line) } } else { if (isset($matches[2]) || in_array($matches[1], $this->voidElements)) { - return; + return null; } if (preg_match('/<\/' . $matches[1] . '>[ ]*$/i', $remainder)) { @@ -925,7 +923,7 @@ protected function blockMarkup($line) protected function blockMarkupContinue($line, array $block) { if (isset($block['closed'])) { - return; + return null; } if (preg_match('/^<' . $block['name'] . '(?:[ ]*' . $this->regexHtmlAttribute . ')*[ ]*>/i', $line['text'])) # open @@ -963,7 +961,8 @@ protected function blockMarkupContinue($line, array $block) */ protected function blockReference($line) { - if (preg_match('/^\[(.+?)\]:[ ]*?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $line['text'], $matches)) { + if (preg_match('/^\[(.+?)\]:[ ]*?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $line['text'], $matches)) //NOSONAR + { $id = strtolower($matches[1]); $Data = array( @@ -977,11 +976,10 @@ protected function blockReference($line) $this->definitionData['Reference'][$id] = $Data; - $block = array( + return array( 'hidden' => true, ); - return $block; } } @@ -994,10 +992,10 @@ protected function blockReference($line) * @param array|null $block The current block being processed. * @return array|null The constructed table block or null if not applicable. */ - protected function blockTable($line, array $block = null) + protected function blockTable($line, array $block = null) //NOSONAR { if (!isset($block) || isset($block['type']) || isset($block['interrupted'])) { - return; + return null; } if (strpos($block['element']['text'], '|') !== false && chop($line['text'], ' -:|') === '') { @@ -1102,10 +1100,10 @@ protected function blockTable($line, array $block = null) * @param array $block The current table block being processed. * @return array|null The updated table block or null if not applicable. */ - protected function blockTableContinue($line, array $block) + protected function blockTableContinue($line, $block) //NOSONAR { if (isset($block['interrupted'])) { - return; + return null; } if ($line['text'][0] === '|' || strpos($line['text'], '|')) { @@ -1158,7 +1156,7 @@ protected function blockTableContinue($line, array $block) */ protected function paragraph($line) { - $block = array( + return array( 'element' => array( 'name' => 'p', 'text' => $line['text'], @@ -1166,7 +1164,6 @@ protected function paragraph($line) ), ); - return $block; } /** @@ -1178,7 +1175,7 @@ protected function paragraph($line) * @param array $nonNestables An array of non-nestable inline types. * @return string The processed markup with inline elements. */ - protected $InlineTypes = array( + protected $inlineTypes = array( '"' => array('SpecialCharacter'), '!' => array('Image'), '&' => array('SpecialCharacter'), @@ -1206,7 +1203,7 @@ protected function paragraph($line) * @param array $nonNestables An array of non-nestable inline types. * @return string The processed markup with inline elements. */ - public function line($text, $nonNestables = array()) + public function line($text, $nonNestables = array()) //NOSONAR { $markup = ''; @@ -1219,7 +1216,7 @@ public function line($text, $nonNestables = array()) $Excerpt = array('text' => $excerpt, 'context' => $text); - foreach ($this->InlineTypes[$marker] as $inlineType) { + foreach ($this->inlineTypes[$marker] as $inlineType) { # check to see if the current inline type is nestable in the current context if (!empty($nonNestables) && in_array($inlineType, $nonNestables)) { @@ -1293,7 +1290,7 @@ protected function inlineCode($Excerpt) if (preg_match('/^(' . $marker . '+)[ ]*(.+?)[ ]*(? strlen($matches[0]), @@ -1346,17 +1343,17 @@ protected function inlineEmailTag($Excerpt) protected function inlineEmphasis($Excerpt) { if (!isset($Excerpt['text'][1])) { - return; + return null; } $marker = $Excerpt['text'][0]; - if ($Excerpt['text'][1] === $marker && preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches)) { + if ($Excerpt['text'][1] === $marker && preg_match($this->strongRegex[$marker], $Excerpt['text'], $matches)) { $emphasis = 'strong'; - } elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches)) { + } elseif (preg_match($this->emRegex[$marker], $Excerpt['text'], $matches)) { $emphasis = 'em'; } else { - return; + return null; } return array( @@ -1398,7 +1395,7 @@ protected function inlineEscapeSequence($Excerpt) protected function inlineImage($Excerpt) { if (!isset($Excerpt['text'][1]) || $Excerpt['text'][1] !== '[') { - return; + return null; } $Excerpt['text'] = substr($Excerpt['text'], 1); @@ -1406,7 +1403,7 @@ protected function inlineImage($Excerpt) $Link = $this->inlineLink($Excerpt); if ($Link === null) { - return; + return null; } $Inline = array( @@ -1450,17 +1447,19 @@ protected function inlineLink($Excerpt) $remainder = $Excerpt['text']; - if (preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches)) { + if (preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches)) //NOSONAR + { $element['text'] = $matches[1]; $extent += strlen($matches[0]); $remainder = substr($remainder, $extent); } else { - return; + return null; } - if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*"|\'[^\']*\'))?\s*[)]/', $remainder, $matches)) { + if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*"|\'[^\']*\'))?\s*[)]/', $remainder, $matches)) //NOSONAR + { $element['attributes']['href'] = $matches[1]; if (isset($matches[2])) { @@ -1479,7 +1478,7 @@ protected function inlineLink($Excerpt) } if (!isset($this->definitionData['Reference'][$definition])) { - return; + return null; } $Definition = $this->definitionData['Reference'][$definition]; @@ -1500,20 +1499,22 @@ protected function inlineLink($Excerpt) * @param array $Excerpt Contains the text to be processed. * @return array|null Returns an array with the markup and its extent, or null if no valid markup is found. */ - protected function inlineMarkup($Excerpt) + protected function inlineMarkup($Excerpt) //NOSONAR { if ($this->markupEscaped || $this->safeMode || strpos($Excerpt['text'], '>') === false) { - return; + return null; } - if ($Excerpt['text'][1] === '/' && preg_match('/^<\/\w[\w-]*[ ]*>/s', $Excerpt['text'], $matches)) { + if ($Excerpt['text'][1] === '/' && preg_match('/^<\/\w[\w-]*[ ]*>/s', $Excerpt['text'], $matches)) //NOSONAR + { return array( 'markup' => $matches[0], 'extent' => strlen($matches[0]), ); } - if ($Excerpt['text'][1] === '!' && preg_match('/^/s', $Excerpt['text'], $matches)) { + if ($Excerpt['text'][1] === '!' && preg_match('/^/s', $Excerpt['text'], $matches)) //NOSONAR + { return array( 'markup' => $matches[0], 'extent' => strlen($matches[0]), @@ -1562,7 +1563,7 @@ protected function inlineSpecialCharacter($Excerpt) protected function inlineStrikethrough($Excerpt) { if (!isset($Excerpt['text'][1])) { - return; + return null; } if ($Excerpt['text'][1] === '~' && preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches)) { @@ -1586,13 +1587,14 @@ protected function inlineStrikethrough($Excerpt) protected function inlineUrl($Excerpt) { if ($this->urlsLinked !== true || !isset($Excerpt['text'][2]) || $Excerpt['text'][2] !== '/') { - return; + return null; } - if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) { + if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) //NOSONAR + { $url = $matches[0][0]; - $Inline = array( + return array( 'extent' => strlen($matches[0][0]), 'position' => $matches[0][1], 'element' => array( @@ -1604,7 +1606,6 @@ protected function inlineUrl($Excerpt) ), ); - return $Inline; } } @@ -1641,9 +1642,9 @@ protected function inlineUrlTag($Excerpt) protected function unmarkedText($text) { if ($this->breaksEnabled) { - $text = preg_replace('/[ ]*\n/', "
\n", $text); + $text = preg_replace('/[ ]*\n/', "
\n", $text); //NOSONAR } else { - $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "
\n", $text); + $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "
\n", $text); //NOSONAR $text = str_replace(" \n", "\n", $text); } @@ -1656,7 +1657,7 @@ protected function unmarkedText($text) * @param array $element The element to be rendered as HTML. * @return string The generated HTML markup for the element. */ - protected function element(array $element) + protected function element(array $element) //NOSONAR { if ($this->safeMode) { $element = $this->sanitiseElement($element); @@ -1761,9 +1762,7 @@ protected function li($lines) */ public function parse($text) { - $markup = $this->text($text); - - return $markup; + return $this->text($text); } /** @@ -1786,12 +1785,8 @@ protected function sanitiseElement(array $element) if (!empty($element['attributes'])) { foreach ($element['attributes'] as $att => $val) { - # filter out badly parsed attribute - if (!preg_match($goodAttribute, $att)) { - unset($element['attributes'][$att]); - } - # dump onevent attribute - elseif (self::striAtStart($att, 'on')) { + # filter out badly parsed attribute or dump onevent attribute + if (!preg_match($goodAttribute, $att) || self::striAtStart($att, 'on')) { unset($element['attributes'][$att]); } } @@ -1889,7 +1884,7 @@ public static function instance($name = 'default') /** * @var array Regular expressions for strong emphasis syntax. */ - protected $StrongRegex = array( + protected $strongRegex = array( '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s', '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us', ); @@ -1897,7 +1892,7 @@ public static function instance($name = 'default') /** * @var array Regular expressions for emphasis syntax. */ - protected $EmRegex = array( + protected $emRegex = array( '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s', '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us', );