| Current Path : /var/www/consult-e-syn/public_html/plugins/system/admintools/feature/ |
| Current File : /var/www/consult-e-syn/public_html/plugins/system/admintools/feature/shield404.php |
<?php
/**
* @package admintools
* @copyright Copyright (c)2010-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
use Joomla\CMS\Application\SiteApplication;
use Joomla\CMS\Exception\ExceptionHandler;
use Joomla\CMS\Factory;
use Joomla\CMS\Uri\Uri;
defined('_JEXEC') || die;
class AtsystemFeatureShield404 extends AtsystemFeatureAbstract
{
private static $previousExceptionHandler;
private static $blockedUrls;
/** @var AtsystemUtilExceptionshandler */
private static $exceptionHandler;
protected $loadOrder = 80;
public static function handleError($error)
{
static::doErrorHandling($error);
}
public static function handleException($exception)
{
// If this isn't a Throwable then bail out
if (!($exception instanceof Throwable) && !($exception instanceof Exception))
{
throw new InvalidArgumentException(
sprintf('The error handler requires an Exception or Throwable object, a "%s" object was given instead.', get_class($exception))
);
}
static::doErrorHandling($exception);
}
private static function doErrorHandling($error)
{
$app = Factory::getApplication();
$isAdmin = false;
if (method_exists($app, 'isClient'))
{
$isAdmin = $app->isClient('administrator');
}
elseif (method_exists($app, 'isAdmin'))
{
$isAdmin = $app->isAdmin();
}
if ($isAdmin || ((int) $error->getCode() !== 404))
{
// Proxy to the previous exception handler if available, otherwise just render the error page
if (self::$previousExceptionHandler)
{
call_user_func_array(self::$previousExceptionHandler, [$error]);
}
else
{
ExceptionHandler::render($error);
}
}
$rows = explode("\n", static::$blockedUrls);
$blockedURLs = array_map('trim', $rows);
$root = Uri::root();
$currentURL = Uri::getInstance();
$currentPath = $currentURL->toString(['scheme', 'host', 'port', 'path']);
// Remove the root from the current path so we can work with relative URLs
$currentPath = str_replace($root, '', $currentPath);
$currentPath = static::removeLanguageTag($currentPath);
$currentPath = trim($currentPath, '/');
$block = false;
foreach ($blockedURLs as $blockPattern)
{
$shouldNegate = false;
// If the pattern starts with a !, we're going to negate the assumption
if (substr($blockPattern, 0, 1) == '!')
{
$blockPattern = substr($blockPattern, 1);
$shouldNegate = true;
}
$blockPattern = trim($blockPattern, '/');
$match = fnmatch($blockPattern, $currentPath);
// Should I invert the result?
if ($shouldNegate)
{
$match = !$match;
}
$block = $match;
// No need to continue if we have to block the request
if ($block)
{
break;
}
}
if ($block)
{
static::$exceptionHandler->logAndAutoban('404shield');
}
// Proxy to the previous exception handler if available, otherwise just render the error page
if (self::$previousExceptionHandler)
{
call_user_func_array(self::$previousExceptionHandler, [$error]);
}
else
{
ExceptionHandler::render($error);
}
}
/**
* Removes the language tag from the URLs generated by multilanguage sites.
*
* @param $pathURL
*
* @return string
*/
private static function removeLanguageTag($pathURL)
{
/** @var SiteApplication $app */
$app = Factory::getApplication();
$hasLanguageFilter = false;
if (method_exists($app, 'getLanguageFilter'))
{
$hasLanguageFilter = $app->getLanguageFilter();
}
if (!$hasLanguageFilter)
{
return $pathURL;
}
$db = Factory::getDbo();
// Let's get the list of SEF code used in the URLs of the published languages
$query = $db->getQuery(true)
->select($db->qn('sef'))
->from($db->qn('#__languages'))
->where($db->qn('published') . ' = ' . $db->q('1'));
$languages = $db->setQuery($query)->loadColumn();
foreach ($languages as $lang)
{
$lang .= '/';
// Replace only the starting string
if (strpos($pathURL, $lang) !== 0)
{
continue;
}
$pathURL = substr($pathURL, strlen($lang));
// There can be only one language tag in the URL, so if we get here it means that there's nothing left to do
break;
}
return $pathURL;
}
/**
* Is this feature enabled?
*
* @return bool
*/
public function isEnabled()
{
// Assign those values to our static variables so we can reference to them in the static context
static::$blockedUrls = $this->cparams->getValue('404shield', "wp-admin.php\nwp-login.php\nwp-content/*\nwp-admin/*");
static::$exceptionHandler = $this->exceptionsHandler;
return ($this->cparams->getValue('404shield_enable', 1));
}
public function onAfterInitialise()
{
// Joomla 3: Set the JError handler for E_ERROR to be the class' handleError method.
if (class_exists('JError'))
{
JError::setErrorHandling(E_ERROR, 'callback', ['AtsystemFeatureShield404', 'handleError']);
}
// Register the previously defined exception handler so we can forward errors to it
self::$previousExceptionHandler = set_exception_handler(['AtsystemFeatureShield404', 'handleException']);
}
}