Файловый менеджер - Редактировать - /home/lmsyaran/public_html/khsh/src.zip
Назад
PK �!�[�$� � Document.phpnu �[��� <?php /** * @package Advanced Template Manager * @version 3.9.5 * * @author Peter van Westen <info@regularlabs.com> * @link http://www.regularlabs.com * @copyright Copyright © 2021 Regular Labs All Rights Reserved * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL */ namespace RegularLabs\Plugin\System\AdvancedTemplates; defined('_JEXEC') or die; use AdvancedTemplatesModelStyle; use Joomla\CMS\Factory as JFactory; use Joomla\CMS\Form\Form as JForm; use Joomla\CMS\Language\Text as JText; use Joomla\CMS\Router\Route as JRoute; use Joomla\Registry\Registry as JRegistry; use RegularLabs\Library\Conditions as RL_Conditions; use RegularLabs\Library\Document as RL_Document; use RegularLabs\Library\Language as RL_Language; use RegularLabs\Library\Parameters as RL_Parameters; use RegularLabs\Library\RegEx as RL_RegEx; class Document { static $style_params; /* * Replace links to com_templates with com_advancedtemplates */ public static function replaceLinks(&$html) { if ( ! RL_Document::isHtml()) { return false; } RL_Language::load('com_advancedtemplates'); if (JFactory::getApplication()->input->get('option') == 'com_templates') { self::replaceLinksInCoreTemplateManager($html); return true; } $html = RL_RegEx::replace( '((["\'])[^\s"\'%]*\?option=com_)(templates(\2|[^a-z-\"\'].*?\2))', '\1advanced\3', $html ); $html = str_replace( [ '?option=com_advancedtemplates&force=1', '?option=com_advancedtemplates&force=1', ], '?option=com_templates', $html ); return true; } public static function replaceLinksInCoreTemplateManager(&$html) { if ( ! Params::get()->show_switch) { return false; } $url = 'index.php?option=com_advancedtemplates'; if (JFactory::getApplication()->input->get('view') == 'style') { $url .= '&task=style.edit&id=' . (int) JFactory::getApplication()->input->get('id'); } $link = '<a style="float:right;" href="' . JRoute::_($url) . '">' . JText::_('ATP_SWITCH_TO_ADVANCED_TEMPLATE_MANAGER') . '</a><div style="clear:both;"></div>'; $html = RL_RegEx::replace('(</div>\s*</form>\s*(<\!--.*?-->\s*)*</div>)', $link . '\1', $html); return true; } public static function setTemplate() { $params = Params::get(); if (JFactory::getApplication()->input->get('templateStyle')) { if (isset($params->template_positions_display) && $params->template_positions_display) { return; } } $active = self::getActiveStyle(); // return if no active template is found if (empty($active)) { return; } // convert params from json to JRegistry object. setTemplate need that. $active->params = new JRegistry($active->params); JFactory::getApplication()->setTemplate($active->template, $active->params); } /** * @return Object The active style */ public static function getActiveStyle() { $styles = self::getStyles(); $active = null; foreach ($styles as $id => &$style) { if ( ! self::isStyleActive($style, $active)) { continue; } $active = $style; break; } return $active; } /** * @return bool True if the current style should be set as active */ public static function isStyleActive(&$style, &$active) { // continue if default language is already set if ($active && $style->home) { return false; } // check if style is set as language default if ($style->home && $style->home == JFactory::getLanguage()->getTag()) { $active = $style; return false; } // check if style is set as main default if ($style->home === 1 || $style->home === '1') { $active = $style; return false; } // continue if style is set as default for a different language if ($style->home) { return false; } // continue is style assignments don't pass if ( ! self::stylePassesAssignments($style)) { return false; } return true; } /** * @return Array An array of template styles with the id as key */ public static function getStyles() { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('s.*') ->from('#__template_styles as s') ->where('s.client_id = 0'); $db->setQuery($query); $styles = $db->loadObjectList('id'); return $styles; } /** * @param $style * * @return Object The advanced parameter object */ public static function getStyleParams($style) { $params = Params::get(); $adv_params = self::getAdvancedParams($style); if ( ! $params->show_assignto_homepage) { $adv_params->assignto_homepage = 0; } if ( ! $params->show_assignto_usergrouplevels) { $adv_params->assignto_usergrouplevels = 0; } if ( ! $params->show_assignto_date) { $adv_params->assignto_date = 0; } if ( ! $params->show_assignto_languages) { $adv_params->assignto_languages = 0; } if ( ! $params->show_assignto_templates) { $adv_params->assignto_templates = 0; } if ( ! $params->show_assignto_urls) { $adv_params->assignto_urls = 0; } if ( ! $params->show_assignto_devices) { $adv_params->assignto_devices = 0; } if ( ! $params->show_assignto_os) { $adv_params->assignto_os = 0; } if ( ! $params->show_assignto_browsers) { $adv_params->assignto_browsers = 0; } if ( ! $params->show_assignto_components) { $adv_params->assignto_components = 0; } if ( ! $params->show_assignto_tags) { $adv_params->show_assignto_tags = 0; } if ( ! $params->show_assignto_content) { $adv_params->assignto_contentpagetypes = 0; $adv_params->assignto_cats = 0; $adv_params->assignto_articles = 0; } return $adv_params; } /** * @param $style * * @return bool */ public static function stylePassesAssignments(&$style) { $params = self::getStyleParams($style); $assignments = RL_Conditions::getConditionsFromParams($params); if ( ! RL_Conditions::hasConditions($assignments)) { return false; } return RL_Conditions::pass($assignments, $params->match_method); } /** * @param $id * * @return object The advanced params for the template style in a json string */ public static function getAdvancedParams($style) { if (isset(self::$style_params[$style->id])) { return self::$style_params[$style->id]; } $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('a.params') ->from('#__advancedtemplates AS a') ->where('a.styleid = ' . (int) $style->id); $db->setQuery($query); $params = $db->loadResult(); // if no params are found in database, get the default params if (empty($params)) { require_once JPATH_ADMINISTRATOR . '/components/com_advancedtemplates/models/style.php'; $model = new AdvancedTemplatesModelStyle; $params = (object) $model->initAssignments($style->id, $style); } self::$style_params[$style->id] = RL_Parameters::getInstance()->getParams($params, JPATH_ADMINISTRATOR . '/components/com_advancedtemplates/assignments.xml'); return self::$style_params[$style->id]; } public static function changeMenuItemForm($form) { if ( ! ($form instanceof JForm)) { return false; } // Check we are manipulating a valid form. $name = $form->getName(); if ($name != 'com_menus.item') { return true; } $form->removeField('template_style_id'); return true; } } PK �!�[����� � Params.phpnu �[��� <?php /** * @package Advanced Template Manager * @version 3.9.5 * * @author Peter van Westen <info@regularlabs.com> * @link http://www.regularlabs.com * @copyright Copyright © 2021 Regular Labs All Rights Reserved * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL */ namespace RegularLabs\Plugin\System\AdvancedTemplates; defined('_JEXEC') or die; use RegularLabs\Library\Parameters as RL_Parameters; class Params { protected static $params = null; public static function get() { if ( ! is_null(self::$params)) { return self::$params; } $params = RL_Parameters::getInstance()->getComponentParams('advancedtemplates'); self::$params = $params; return self::$params; } } PK "�[�J�E� � Extension/NamespaceMap.phpnu �[��� <?php /** * @package Joomla.Plugin * @subpackage Extension.namespacemap * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\Extension\NamespaceMap\Extension; use Joomla\CMS\Installer\Installer; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\DispatcherInterface; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla! namespace map creator / updater. * * @since 4.0.0 */ final class NamespaceMap extends CMSPlugin { /** * The namespace map file creator * * @var \JNamespacePsr4Map */ private $fileCreator = null; /** * Constructor * * @param DispatcherInterface $subject The object to observe * @param \JNamespacePsr4Map $map The namespace map creator * @param array $config An optional associative array of configuration settings. * Recognized key values include 'name', 'group', 'params', 'language' * (this list is not meant to be comprehensive). * * @since 4.0.0 */ public function __construct(DispatcherInterface $dispatcher, \JNamespacePsr4Map $map, array $config = []) { $this->fileCreator = $map; parent::__construct($dispatcher, $config); } /** * Update / Create map on extension install * * @param Installer $installer Installer instance * @param integer $eid Extension id * * @return void * * @since 4.0.0 */ public function onExtensionAfterInstall($installer, $eid) { // Check that we have a valid extension if ($eid) { // Update / Create new map $this->fileCreator->create(); } } /** * Update / Create map on extension uninstall * * @param Installer $installer Installer instance * @param integer $eid Extension id * @param boolean $removed Installation result * * @return void * * @since 4.0.0 */ public function onExtensionAfterUninstall($installer, $eid, $removed) { // Check that we have a valid extension and that it has been removed if ($eid && $removed) { // Update / Create new map $this->fileCreator->create(); } } /** * Update map on extension update * * @param Installer $installer Installer instance * @param integer $eid Extension id * * @return void * * @since 4.0.0 */ public function onExtensionAfterUpdate($installer, $eid) { // Check that we have a valid extension if ($eid) { // Update / Create new map $this->fileCreator->create(); } } } PK I'�[��à� � JavascriptRenderer.phpnu �[��� <?php /** * @package Joomla.Plugin * @subpackage System.Debug * * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug; use DebugBar\DebugBar; use DebugBar\JavascriptRenderer as DebugBarJavascriptRenderer; use Joomla\CMS\Factory; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Custom JavascriptRenderer for DebugBar * * @since 4.0.0 */ class JavascriptRenderer extends DebugBarJavascriptRenderer { /** * Class constructor. * * @param \DebugBar\DebugBar $debugBar DebugBar instance * @param string $baseUrl The base URL from which assets will be served * @param string $basePath The path which assets are relative to * * @since 4.0.0 */ public function __construct(DebugBar $debugBar, $baseUrl = null, $basePath = null) { parent::__construct($debugBar, $baseUrl, $basePath); // Disable features that loaded by Joomla! API, or not in use $this->setEnableJqueryNoConflict(false); $this->disableVendor('jquery'); $this->disableVendor('fontawesome'); } /** * Renders the html to include needed assets * * Only useful if Assetic is not used * * @return string * * @since 4.0.0 */ public function renderHead() { list($cssFiles, $jsFiles, $inlineCss, $inlineJs, $inlineHead) = $this->getAssets(null, self::RELATIVE_URL); $html = ''; $doc = Factory::getApplication()->getDocument(); foreach ($cssFiles as $file) { $html .= sprintf('<link rel="stylesheet" type="text/css" href="%s">' . "\n", $file); } foreach ($inlineCss as $content) { $html .= sprintf('<style>%s</style>' . "\n", $content); } foreach ($jsFiles as $file) { $html .= sprintf('<script type="text/javascript" src="%s" defer></script>' . "\n", $file); } $nonce = ''; if ($doc->cspNonce) { $nonce = ' nonce="' . $doc->cspNonce . '"'; } foreach ($inlineJs as $content) { $html .= sprintf('<script type="module"%s>%s</script>' . "\n", $nonce, $content); } foreach ($inlineHead as $content) { $html .= $content . "\n"; } return $html; } /** * Returns the code needed to display the debug bar * * AJAX request should not render the initialization code. * * @param boolean $initialize Whether or not to render the debug bar initialization code * @param boolean $renderStackedData Whether or not to render the stacked data * * @return string * * @since 4.0.0 */ public function render($initialize = true, $renderStackedData = true) { $js = ''; $doc = Factory::getApplication()->getDocument(); if ($initialize) { $js = $this->getJsInitializationCode(); } if ($renderStackedData && $this->debugBar->hasStackedData()) { foreach ($this->debugBar->getStackedData() as $id => $data) { $js .= $this->getAddDatasetCode($id, $data, '(stacked)'); } } $suffix = !$initialize ? '(ajax)' : null; $js .= $this->getAddDatasetCode($this->debugBar->getCurrentRequestId(), $this->debugBar->getData(), $suffix); $nonce = ''; if ($doc->cspNonce) { $nonce = ' nonce="' . $doc->cspNonce . '"'; } if ($this->useRequireJs) { return "<script type=\"module\"$nonce>\nrequire(['debugbar'], function(PhpDebugBar){ $js });\n</script>\n"; } return "<script type=\"module\"$nonce>\n$js\n</script>\n"; } } PK I'�[osa�> > JoomlaHttpDriver.phpnu �[��� <?php /** * @package Joomla.Plugin * @subpackage System.Debug * * @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug; use DebugBar\HttpDriverInterface; use Joomla\Application\WebApplicationInterface; use Joomla\CMS\Application\CMSApplicationInterface; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla HTTP driver for DebugBar * * @since 4.1.5 */ final class JoomlaHttpDriver implements HttpDriverInterface { /** * @var CMSApplicationInterface * * @since 4.1.5 */ private $app; /** * @var array * * @since 4.1.5 */ private $dummySession = []; /** * Constructor. * * @param CMSApplicationInterface $app * * @since 4.1.5 */ public function __construct(CMSApplicationInterface $app) { $this->app = $app; } /** * Sets HTTP headers * * @param array $headers * * @since 4.1.5 */ public function setHeaders(array $headers) { if ($this->app instanceof WebApplicationInterface) { foreach ($headers as $name => $value) { $this->app->setHeader($name, $value, true); } } } /** * Checks if the session is started * * @return boolean * * @since 4.1.5 */ public function isSessionStarted() { return true; } /** * Sets a value in the session * * @param string $name * @param string $value * * @since 4.1.5 */ public function setSessionValue($name, $value) { $this->dummySession[$name] = $value; } /** * Checks if a value is in the session * * @param string $name * * @return boolean * * @since 4.1.5 */ public function hasSessionValue($name) { return \array_key_exists($name, $this->dummySession); } /** * Returns a value from the session * * @param string $name * * @return mixed * * @since 4.1.5 */ public function getSessionValue($name) { return $this->dummySession[$name] ?? null; } /** * Deletes a value from the session * * @param string $name * * @since 4.1.5 */ public function deleteSessionValue($name) { unset($this->dummySession[$name]); } } PK I'�[���< < DataFormatter.phpnu �[��� <?php /** * @package Joomla.Plugin * @subpackage System.Debug * * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug; use DebugBar\DataFormatter\DataFormatter as DebugBarDataFormatter; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * DataFormatter * * @since 4.0.0 */ class DataFormatter extends DebugBarDataFormatter { /** * Strip the root path. * * @param string $path The path. * @param string $replacement The replacement * * @return string * * @since 4.0.0 */ public function formatPath($path, $replacement = ''): string { return str_replace(JPATH_ROOT, $replacement, $path); } /** * Format a string from back trace. * * @param array $call The array to format * * @return string * * @since 4.0.0 */ public function formatCallerInfo(array $call): string { $string = ''; if (isset($call['class'])) { // If entry has Class/Method print it. $string .= htmlspecialchars($call['class'] . $call['type'] . $call['function']) . '()'; } elseif (isset($call['args'][0]) && \is_array($call['args'][0])) { $string .= htmlspecialchars($call['function']) . ' ('; foreach ($call['args'][0] as $arg) { // Check if the arguments can be used as string if (\is_object($arg) && !method_exists($arg, '__toString')) { $arg = \get_class($arg); } // Keep only the size of array if (\is_array($arg)) { $arg = 'Array(count=' . \count($arg) . ')'; } $string .= htmlspecialchars($arg) . ', '; } $string = rtrim($string, ', ') . ')'; } elseif (isset($call['args'][0])) { $string .= htmlspecialchars($call['function']) . '('; if (\is_scalar($call['args'][0])) { $string .= $call['args'][0]; } elseif (\is_object($call['args'][0])) { $string .= \get_class($call['args'][0]); } else { $string .= \gettype($call['args'][0]); } $string .= ')'; } else { // It's a function. $string .= htmlspecialchars($call['function']) . '()'; } return $string; } } PK I'�[�g�S\ S\ Extension/Debug.phpnu �[��� <?php /** * @package Joomla.Plugin * @subpackage System.debug * * @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug\Extension; use DebugBar\DataCollector\MessagesCollector; use DebugBar\DebugBar; use DebugBar\OpenHandler; use Joomla\Application\ApplicationEvents; use Joomla\CMS\Application\CMSApplicationInterface; use Joomla\CMS\Document\HtmlDocument; use Joomla\CMS\Event\Plugin\AjaxEvent; use Joomla\CMS\Log\Log; use Joomla\CMS\Log\LogEntry; use Joomla\CMS\Log\Logger\InMemoryLogger; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Profiler\Profiler; use Joomla\CMS\Session\Session; use Joomla\CMS\Uri\Uri; use Joomla\Database\DatabaseAwareTrait; use Joomla\Database\DatabaseInterface; use Joomla\Database\Event\ConnectionEvent; use Joomla\Event\DispatcherInterface; use Joomla\Event\Priority; use Joomla\Event\SubscriberInterface; use Joomla\Plugin\System\Debug\DataCollector\InfoCollector; use Joomla\Plugin\System\Debug\DataCollector\LanguageErrorsCollector; use Joomla\Plugin\System\Debug\DataCollector\LanguageFilesCollector; use Joomla\Plugin\System\Debug\DataCollector\LanguageStringsCollector; use Joomla\Plugin\System\Debug\DataCollector\MemoryCollector; use Joomla\Plugin\System\Debug\DataCollector\ProfileCollector; use Joomla\Plugin\System\Debug\DataCollector\QueryCollector; use Joomla\Plugin\System\Debug\DataCollector\RequestDataCollector; use Joomla\Plugin\System\Debug\DataCollector\SessionCollector; use Joomla\Plugin\System\Debug\DataCollector\UserCollector; use Joomla\Plugin\System\Debug\JavascriptRenderer; use Joomla\Plugin\System\Debug\JoomlaHttpDriver; use Joomla\Plugin\System\Debug\Storage\FileStorage; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Joomla! Debug plugin. * * @since 1.5 */ final class Debug extends CMSPlugin implements SubscriberInterface { use DatabaseAwareTrait; /** * List of protected keys that will be redacted in multiple data collected * * @since 4.2.4 */ public const PROTECTED_COLLECTOR_KEYS = "/password|passwd|pwd|secret|token|server_auth|_pass|smtppass|otpKey|otep/i"; /** * True if debug lang is on. * * @var boolean * @since 3.0 */ private $debugLang; /** * Holds log entries handled by the plugin. * * @var LogEntry[] * @since 3.1 */ private $logEntries = []; /** * Holds all SHOW PROFILE FOR QUERY n, indexed by n-1. * * @var array * @since 3.1.2 */ private $sqlShowProfileEach = []; /** * Holds all EXPLAIN EXTENDED for all queries. * * @var array * @since 3.1.2 */ private $explains = []; /** * @var DebugBar * @since 4.0.0 */ private $debugBar; /** * The query monitor. * * @var \Joomla\Database\Monitor\DebugMonitor * @since 4.0.0 */ private $queryMonitor; /** * AJAX marker * * @var bool * @since 4.0.0 */ protected $isAjax = false; /** * Whether displaying a logs is enabled * * @var bool * @since 4.0.0 */ protected $showLogs = false; /** * The time spent in onAfterDisconnect() * * @var float * @since 4.4.0 */ protected $timeInOnAfterDisconnect = 0; /** * @return array * * @since 4.1.3 */ public static function getSubscribedEvents(): array { return [ 'onBeforeCompileHead' => 'onBeforeCompileHead', 'onAjaxDebug' => 'onAjaxDebug', 'onBeforeRespond' => 'onBeforeRespond', 'onAfterRespond' => [ 'onAfterRespond', Priority::MIN, ], ApplicationEvents::AFTER_RESPOND => [ 'onAfterRespond', Priority::MIN, ], 'onAfterDisconnect' => 'onAfterDisconnect', ]; } /** * @param DispatcherInterface $dispatcher The object to observe -- event dispatcher. * @param array $config An optional associative array of configuration settings. * @param CMSApplicationInterface $app The app * @param DatabaseInterface $db The db * * @since 1.5 */ public function __construct(DispatcherInterface $dispatcher, array $config, CMSApplicationInterface $app, DatabaseInterface $db) { parent::__construct($dispatcher, $config); $this->setApplication($app); $this->setDatabase($db); $this->debugLang = $this->getApplication()->get('debug_lang'); // Skip the plugin if debug is off if (!$this->debugLang && !$this->getApplication()->get('debug')) { return; } $this->getApplication()->set('gzip', false); ob_start(); ob_implicit_flush(false); /** @var \Joomla\Database\Monitor\DebugMonitor */ $this->queryMonitor = $this->getDatabase()->getMonitor(); if (!$this->params->get('queries', 1)) { // Remove the database driver monitor $this->getDatabase()->setMonitor(null); } $this->debugBar = new DebugBar(); // Check whether we want to track the request history for future use. if ($this->params->get('track_request_history', false)) { $storagePath = JPATH_CACHE . '/plg_system_debug_' . $this->getApplication()->getName(); $this->debugBar->setStorage(new FileStorage($storagePath)); } $this->debugBar->setHttpDriver(new JoomlaHttpDriver($this->getApplication())); $this->isAjax = $this->getApplication()->getInput()->get('option') === 'com_ajax' && $this->getApplication()->getInput()->get('plugin') === 'debug' && $this->getApplication()->getInput()->get('group') === 'system'; $this->showLogs = (bool) $this->params->get('logs', true); // Log deprecated class aliases if ($this->showLogs && $this->getApplication()->get('log_deprecated')) { foreach (\JLoader::getDeprecatedAliases() as $deprecation) { Log::add( sprintf( '%1$s has been aliased to %2$s and the former class name is deprecated. The alias will be removed in %3$s.', $deprecation['old'], $deprecation['new'], $deprecation['version'] ), Log::WARNING, 'deprecation-notes' ); } } } /** * Add an assets for debugger. * * @return void * * @since 4.0.0 */ public function onBeforeCompileHead() { // Only if debugging or language debug is enabled. if ((JDEBUG || $this->debugLang) && $this->isAuthorisedDisplayDebug() && $this->getApplication()->getDocument() instanceof HtmlDocument) { // Use our own jQuery and fontawesome instead of the debug bar shipped version $assetManager = $this->getApplication()->getDocument()->getWebAssetManager(); $assetManager->registerAndUseStyle( 'plg.system.debug', 'plg_system_debug/debug.css', [], [], ['fontawesome'] ); $assetManager->registerAndUseScript( 'plg.system.debug', 'plg_system_debug/debug.min.js', [], ['defer' => true], ['jquery'] ); } // Disable asset media version if needed. if (JDEBUG && (int) $this->params->get('refresh_assets', 1) === 0) { $this->getApplication()->getDocument()->setMediaVersion(''); } } /** * Show the debug info. * * @return void * * @since 1.6 */ public function onAfterRespond() { $endTime = microtime(true) - $this->timeInOnAfterDisconnect; $endMemory = memory_get_peak_usage(false); // Do not collect data if debugging or language debug is not enabled. if ((!JDEBUG && !$this->debugLang) || $this->isAjax) { return; } // User has to be authorised to see the debug information. if (!$this->isAuthorisedDisplayDebug()) { return; } // Load language. $this->loadLanguage(); $this->debugBar->addCollector(new InfoCollector($this->params, $this->debugBar->getCurrentRequestId())); $this->debugBar->addCollector(new UserCollector()); if (JDEBUG) { if ($this->params->get('memory', 1)) { $this->debugBar->addCollector(new MemoryCollector($this->params, $endMemory)); } if ($this->params->get('request', 1)) { $this->debugBar->addCollector(new RequestDataCollector()); } if ($this->params->get('session', 1)) { $this->debugBar->addCollector(new SessionCollector($this->params, true)); } if ($this->params->get('profile', 1)) { $this->debugBar->addCollector((new ProfileCollector($this->params))->setRequestEndTime($endTime)); } if ($this->params->get('queries', 1)) { // Remember session form token for possible future usage. $formToken = Session::getFormToken(); // Close session to collect possible session-related queries. $this->getApplication()->getSession()->close(); // Call $db->disconnect() here to trigger the onAfterDisconnect() method here in this class! $this->getDatabase()->disconnect(); $this->debugBar->addCollector(new QueryCollector($this->params, $this->queryMonitor, $this->sqlShowProfileEach, $this->explains)); } if ($this->showLogs) { $this->collectLogs(); } } if ($this->debugLang) { $this->debugBar->addCollector(new LanguageFilesCollector($this->params)); $this->debugBar->addCollector(new LanguageStringsCollector($this->params)); $this->debugBar->addCollector(new LanguageErrorsCollector($this->params)); } // Only render for HTML output. if (!($this->getApplication()->getDocument() instanceof HtmlDocument)) { $this->debugBar->stackData(); return; } $debugBarRenderer = new JavascriptRenderer($this->debugBar, Uri::root(true) . '/media/vendor/debugbar/'); $openHandlerUrl = Uri::base(true) . '/index.php?option=com_ajax&plugin=debug&group=system&format=raw&action=openhandler'; $openHandlerUrl .= '&' . ($formToken ?? Session::getFormToken()) . '=1'; $debugBarRenderer->setOpenHandlerUrl($openHandlerUrl); /** * @todo disable highlightjs from the DebugBar, import it through NPM * and deliver it through Joomla's API * Also every DebugBar script and stylesheet needs to use Joomla's API * $debugBarRenderer->disableVendor('highlightjs'); */ // Capture output. $contents = ob_get_contents(); if ($contents) { ob_end_clean(); } // No debug for Safari and Chrome redirection. if ( strpos($contents, '<html><head><meta http-equiv="refresh" content="0;') === 0 && strpos(strtolower($_SERVER['HTTP_USER_AGENT'] ?? ''), 'webkit') !== false ) { $this->debugBar->stackData(); echo $contents; return; } echo str_replace('</body>', $debugBarRenderer->renderHead() . $debugBarRenderer->render() . '</body>', $contents); } /** * AJAX handler * * @param AjaxEvent $event * * @return void * * @since 4.0.0 */ public function onAjaxDebug(AjaxEvent $event) { // Do not render if debugging or language debug is not enabled. if (!JDEBUG && !$this->debugLang) { return; } // User has to be authorised to see the debug information. if (!$this->isAuthorisedDisplayDebug() || !Session::checkToken('request')) { return; } switch ($this->getApplication()->getInput()->get('action')) { case 'openhandler': $handler = new OpenHandler($this->debugBar); $result = $handler->handle($this->getApplication()->getInput()->request->getArray(), false, false); $event->addResult($result); } } /** * Method to check if the current user is allowed to see the debug information or not. * * @return boolean True if access is allowed. * * @since 3.0 */ private function isAuthorisedDisplayDebug(): bool { static $result; if ($result !== null) { return $result; } // If the user is not allowed to view the output then end here. $filterGroups = (array) $this->params->get('filter_groups', []); if (!empty($filterGroups)) { $userGroups = $this->getApplication()->getIdentity()->get('groups'); if (!array_intersect($filterGroups, $userGroups)) { $result = false; return false; } } $result = true; return true; } /** * Disconnect handler for database to collect profiling and explain information. * * @param ConnectionEvent $event Event object * * @return void * * @since 4.0.0 */ public function onAfterDisconnect(ConnectionEvent $event) { if (!JDEBUG) { return; } $startTime = microtime(true); $db = $event->getDriver(); // Remove the monitor to avoid monitoring the following queries $db->setMonitor(null); if ($this->params->get('query_profiles') && $db->getServerType() === 'mysql') { try { // Check if profiling is enabled. $db->setQuery("SHOW VARIABLES LIKE 'have_profiling'"); $hasProfiling = $db->loadResult(); if ($hasProfiling) { // Run a SHOW PROFILE query. $db->setQuery('SHOW PROFILES'); $sqlShowProfiles = $db->loadAssocList(); if ($sqlShowProfiles) { foreach ($sqlShowProfiles as $qn) { // Run SHOW PROFILE FOR QUERY for each query where a profile is available (max 100). $db->setQuery('SHOW PROFILE FOR QUERY ' . (int) $qn['Query_ID']); $this->sqlShowProfileEach[$qn['Query_ID'] - 1] = $db->loadAssocList(); } } } else { $this->sqlShowProfileEach[0] = [['Error' => 'MySql have_profiling = off']]; } } catch (\Exception $e) { $this->sqlShowProfileEach[0] = [['Error' => $e->getMessage()]]; } } if ($this->params->get('query_explains') && \in_array($db->getServerType(), ['mysql', 'postgresql'], true)) { $logs = $this->queryMonitor->getLogs(); $boundParams = $this->queryMonitor->getBoundParams(); foreach ($logs as $k => $query) { $dbVersion56 = $db->getServerType() === 'mysql' && version_compare($db->getVersion(), '5.6', '>='); $dbVersion80 = $db->getServerType() === 'mysql' && version_compare($db->getVersion(), '8.0', '>='); if ($dbVersion80) { $dbVersion56 = false; } if ((stripos($query, 'select') === 0) || ($dbVersion56 && ((stripos($query, 'delete') === 0) || (stripos($query, 'update') === 0)))) { try { $queryInstance = $db->getQuery(true); $queryInstance->setQuery('EXPLAIN ' . ($dbVersion56 ? 'EXTENDED ' : '') . $query); if ($boundParams[$k]) { foreach ($boundParams[$k] as $key => $obj) { $queryInstance->bind($key, $obj->value, $obj->dataType, $obj->length, $obj->driverOptions); } } $this->explains[$k] = $db->setQuery($queryInstance)->loadAssocList(); } catch (\Exception $e) { $this->explains[$k] = [['error' => $e->getMessage()]]; } } } } $this->timeInOnAfterDisconnect = microtime(true) - $startTime; } /** * Store log messages so they can be displayed later. * This function is passed log entries by JLogLoggerCallback. * * @param LogEntry $entry A log entry. * * @return void * * @since 3.1 * * @deprecated 4.3 will be removed in 6.0 * Use \Joomla\CMS\Log\Log::add(LogEntry $entry) instead */ public function logger(LogEntry $entry) { if (!$this->showLogs) { return; } $this->logEntries[] = $entry; } /** * Collect log messages. * * @return void * * @since 4.0.0 */ private function collectLogs() { $loggerOptions = ['group' => 'default']; $logger = new InMemoryLogger($loggerOptions); $logEntries = $logger->getCollectedEntries(); if (!$this->logEntries && !$logEntries) { return; } if ($this->logEntries) { $logEntries = array_merge($logEntries, $this->logEntries); } $logDeprecated = $this->getApplication()->get('log_deprecated', 0); $logDeprecatedCore = $this->params->get('log-deprecated-core', 0); $this->debugBar->addCollector(new MessagesCollector('log')); if ($logDeprecated) { $this->debugBar->addCollector(new MessagesCollector('deprecated')); $this->debugBar->addCollector(new MessagesCollector('deprecation-notes')); } if ($logDeprecatedCore) { $this->debugBar->addCollector(new MessagesCollector('deprecated-core')); } foreach ($logEntries as $entry) { switch ($entry->category) { case 'deprecation-notes': if ($logDeprecated) { $this->debugBar[$entry->category]->addMessage($entry->message); } break; case 'deprecated': if (!$logDeprecated && !$logDeprecatedCore) { break; } $file = ''; $line = ''; // Find the caller, skip Log methods and trigger_error function foreach ($entry->callStack as $stackEntry) { if ( !empty($stackEntry['class']) && ($stackEntry['class'] === 'Joomla\CMS\Log\LogEntry' || $stackEntry['class'] === 'Joomla\CMS\Log\Log') ) { continue; } if ( empty($stackEntry['class']) && !empty($stackEntry['function']) && $stackEntry['function'] === 'trigger_error' ) { continue; } $file = $stackEntry['file'] ?? ''; $line = $stackEntry['line'] ?? ''; break; } $category = $entry->category; $relative = $file ? str_replace(JPATH_ROOT, '', $file) : ''; if ($relative && 0 === strpos($relative, '/libraries/src')) { if (!$logDeprecatedCore) { break; } $category .= '-core'; } elseif (!$logDeprecated) { break; } $message = [ 'message' => $entry->message, 'caller' => $file . ':' . $line, // @todo 'stack' => $entry->callStack; ]; $this->debugBar[$category]->addMessage($message, 'warning'); break; case 'databasequery': // Should be collected by its own collector break; default: switch ($entry->priority) { case Log::EMERGENCY: case Log::ALERT: case Log::CRITICAL: case Log::ERROR: $level = 'error'; break; case Log::WARNING: $level = 'warning'; break; default: $level = 'info'; } $this->debugBar['log']->addMessage($entry->category . ' - ' . $entry->message, $level); break; } } } /** * Add server timing headers when profile is activated. * * @return void * * @since 4.1.0 */ public function onBeforeRespond(): void { if (!JDEBUG || !$this->params->get('profile', 1)) { return; } $metrics = ''; $moduleTime = 0; $accessTime = 0; foreach (Profiler::getInstance('Application')->getMarks() as $index => $mark) { // Ignore the before mark as the after one contains the timing of the action if (stripos($mark->label, 'before') !== false) { continue; } // Collect the module render time if (strpos($mark->label, 'mod_') !== false) { $moduleTime += $mark->time; continue; } // Collect the access render time if (strpos($mark->label, 'Access:') !== false) { $accessTime += $mark->time; continue; } $desc = str_ireplace('after', '', $mark->label); $name = preg_replace('/[^\da-z]/i', '', $desc); $metrics .= sprintf('%s;dur=%f;desc="%s", ', $index . $name, $mark->time, $desc); // Do not create too large headers, some web servers don't love them if (\strlen($metrics) > 3000) { $metrics .= 'System;dur=0;desc="Data truncated to 3000 characters", '; break; } } // Add the module entry $metrics .= 'Modules;dur=' . $moduleTime . ';desc="Modules", '; // Add the access entry $metrics .= 'Access;dur=' . $accessTime . ';desc="Access"'; $this->getApplication()->setHeader('Server-Timing', $metrics); } } PK I'�[z�,�Y Y AbstractDataCollector.phpnu �[��� <?php /** * @package Joomla.Plugin * @subpackage System.Debug * * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Plugin\System\Debug; use DebugBar\DataCollector\DataCollector; use DebugBar\DataCollector\Renderable; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * AbstractDataCollector * * @since 4.0.0 */ abstract class AbstractDataCollector extends DataCollector implements Renderable { /** * Parameters. * * @var Registry * @since 4.0.0 */ protected $params; /** * The default formatter. * * @var DataFormatter * @since 4.0.0 */ public static $defaultDataFormatter; /** * AbstractDataCollector constructor. * * @param Registry $params Parameters. * * @since 4.0.0 */ public function __construct(Registry $params) { $this->params = $params; } /** * Get a data formatter. * * @since 4.0.0 * @return DataFormatter */ public function getDataFormatter(): DataFormatter { if ($this->dataFormater === null) { $this->dataFormater = self::getDefaultDataFormatter(); } return $this->dataFormater; } /** * Returns the default data formatter * * @since 4.0.0 * @return DataFormatter */ public static function getDefaultDataFormatter(): DataFormatter { if (self::$defaultDataFormatter === null) { self::$defaultDataFormatter = new DataFormatter(); } return self::$defaultDataFormatter; } /** * Strip the Joomla! root path. * * @param string $path The path. * * @return string * * @since 4.0.0 */ public function formatPath($path): string { return $this->getDataFormatter()->formatPath($path); } /** * Format a string from back trace. * * @param array $call The array to format * * @return string * * @since 4.0.0 */ public function formatCallerInfo(array $call): string { return $this->getDataFormatter()->formatCallerInfo($call); } } PK I'�[*^f`! `! "