diff options
| author | Charles Cabergs <me@cacharle.xyz> | 2020-07-27 10:05:23 +0200 |
|---|---|---|
| committer | Charles Cabergs <me@cacharle.xyz> | 2020-07-27 10:05:23 +0200 |
| commit | 5bf66662a9bdd62c5bccab15e607cd95cfb8fcab (patch) | |
| tree | 39a1a4629749056191c05dfd899f931701b7acf3 /srcs/phpmyadmin/libraries/classes/Advisor.php | |
| parent | 5afd237bbd22028b85532b8c0b3fcead49a00764 (diff) | |
| download | ft_server-5bf66662a9bdd62c5bccab15e607cd95cfb8fcab.tar.gz ft_server-5bf66662a9bdd62c5bccab15e607cd95cfb8fcab.tar.bz2 ft_server-5bf66662a9bdd62c5bccab15e607cd95cfb8fcab.zip | |
Removed wordpress and phpmyadmin, my server doesn't handle it well and it brings shame on my famillyHEADmaster
Diffstat (limited to 'srcs/phpmyadmin/libraries/classes/Advisor.php')
| -rw-r--r-- | srcs/phpmyadmin/libraries/classes/Advisor.php | 707 |
1 files changed, 0 insertions, 707 deletions
diff --git a/srcs/phpmyadmin/libraries/classes/Advisor.php b/srcs/phpmyadmin/libraries/classes/Advisor.php deleted file mode 100644 index 6dad8b6..0000000 --- a/srcs/phpmyadmin/libraries/classes/Advisor.php +++ /dev/null @@ -1,707 +0,0 @@ -<?php -/* vim: set expandtab sw=4 ts=4 sts=4: */ -/** - * A simple rules engine, that parses and executes the rules in advisory_rules.txt. - * Adjusted to phpMyAdmin. - * - * @package PhpMyAdmin - */ -declare(strict_types=1); - -namespace PhpMyAdmin; - -use Exception; -use PhpMyAdmin\Core; -use PhpMyAdmin\DatabaseInterface; -use PhpMyAdmin\SysInfo; -use PhpMyAdmin\Url; -use PhpMyAdmin\Util; -use Symfony\Component\ExpressionLanguage\ExpressionLanguage; -use Throwable; -use function array_merge_recursive; - -/** - * Advisor class - * - * @package PhpMyAdmin - */ -class Advisor -{ - public const GENERIC_RULES_FILE = 'libraries/advisory_rules_generic.txt'; - public const BEFORE_MYSQL80003_RULES_FILE = 'libraries/advisory_rules_mysql_before80003.txt'; - - protected $dbi; - protected $variables; - protected $globals; - protected $parseResult; - protected $runResult; - protected $expression; - - /** - * Constructor - * - * @param DatabaseInterface $dbi DatabaseInterface object - * @param ExpressionLanguage $expression ExpressionLanguage object - */ - public function __construct(DatabaseInterface $dbi, ExpressionLanguage $expression) - { - $this->dbi = $dbi; - $this->expression = $expression; - /* - * Register functions for ExpressionLanguage, we intentionally - * do not implement support for compile as we do not use it. - */ - $this->expression->register( - 'round', - function () { - }, - function ($arguments, $num) { - return round($num); - } - ); - $this->expression->register( - 'substr', - function () { - }, - function ($arguments, $string, $start, $length) { - return substr($string, $start, $length); - } - ); - $this->expression->register( - 'preg_match', - function () { - }, - function ($arguments, $pattern, $subject) { - return preg_match($pattern, $subject); - } - ); - $this->expression->register( - 'ADVISOR_bytime', - function () { - }, - function ($arguments, $num, $precision) { - return self::byTime($num, $precision); - } - ); - $this->expression->register( - 'ADVISOR_timespanFormat', - function () { - }, - function ($arguments, $seconds) { - return self::timespanFormat((int) $seconds); - } - ); - $this->expression->register( - 'ADVISOR_formatByteDown', - function () { - }, - function ($arguments, $value, $limes = 6, $comma = 0) { - return self::formatByteDown($value, $limes, $comma); - } - ); - $this->expression->register( - 'fired', - function () { - }, - function ($arguments, $value) { - if (! isset($this->runResult['fired'])) { - return 0; - } - - // Did matching rule fire? - foreach ($this->runResult['fired'] as $rule) { - if ($rule['id'] == $value) { - return '1'; - } - } - - return '0'; - } - ); - /* Some global variables for advisor */ - $this->globals = [ - 'PMA_MYSQL_INT_VERSION' => $this->dbi->getVersion(), - ]; - } - - /** - * Get variables - * - * @return mixed - */ - public function getVariables() - { - return $this->variables; - } - - /** - * Set variables - * - * @param array $variables Variables - * - * @return Advisor - */ - public function setVariables(array $variables): self - { - $this->variables = $variables; - - return $this; - } - - /** - * Set a variable and its value - * - * @param string|int $variable Variable to set - * @param mixed $value Value to set - * - * @return Advisor - */ - public function setVariable($variable, $value): self - { - $this->variables[$variable] = $value; - - return $this; - } - - /** - * Get parseResult - * - * @return mixed - */ - public function getParseResult() - { - return $this->parseResult; - } - - /** - * Set parseResult - * - * @param array $parseResult Parse result - * - * @return Advisor - */ - public function setParseResult(array $parseResult): self - { - $this->parseResult = $parseResult; - - return $this; - } - - /** - * Get runResult - * - * @return mixed - */ - public function getRunResult() - { - return $this->runResult; - } - - /** - * Set runResult - * - * @param array $runResult Run result - * - * @return Advisor - */ - public function setRunResult(array $runResult): self - { - $this->runResult = $runResult; - - return $this; - } - - /** - * Parses and executes advisor rules - * - * @return array with run and parse results - */ - public function run(): array - { - // HowTo: A simple Advisory system in 3 easy steps. - - // Step 1: Get some variables to evaluate on - $this->setVariables( - array_merge( - $this->dbi->fetchResult('SHOW GLOBAL STATUS', 0, 1), - $this->dbi->fetchResult('SHOW GLOBAL VARIABLES', 0, 1) - ) - ); - - // Add total memory to variables as well - $sysinfo = SysInfo::get(); - $memory = $sysinfo->memory(); - $this->variables['system_memory'] - = isset($memory['MemTotal']) ? $memory['MemTotal'] : 0; - - $ruleFiles = $this->defineRulesFiles(); - - // Step 2: Read and parse the list of rules - $parsedResults = []; - foreach ($ruleFiles as $ruleFile) { - $parsedResults[] = $this->parseRulesFile($ruleFile); - } - $this->setParseResult(array_merge_recursive(...$parsedResults)); - - // Step 3: Feed the variables to the rules and let them fire. Sets - // $runResult - $this->runRules(); - - return [ - 'parse' => ['errors' => $this->parseResult['errors']], - 'run' => $this->runResult, - ]; - } - - /** - * Stores current error in run results. - * - * @param string $description description of an error. - * @param Throwable $exception exception raised - * - * @return void - */ - public function storeError(string $description, Throwable $exception): void - { - $this->runResult['errors'][] = $description - . ' ' - . sprintf( - __('Error when evaluating: %s'), - $exception->getMessage() - ); - } - - /** - * Executes advisor rules - * - * @return boolean - */ - public function runRules(): bool - { - $this->setRunResult( - [ - 'fired' => [], - 'notfired' => [], - 'unchecked' => [], - 'errors' => [], - ] - ); - - foreach ($this->parseResult['rules'] as $rule) { - $this->variables['value'] = 0; - $precond = true; - - if (isset($rule['precondition'])) { - try { - $precond = $this->ruleExprEvaluate($rule['precondition']); - } catch (Exception $e) { - $this->storeError( - sprintf( - __('Failed evaluating precondition for rule \'%s\'.'), - $rule['name'] - ), - $e - ); - continue; - } - } - - if (! $precond) { - $this->addRule('unchecked', $rule); - } else { - try { - $value = $this->ruleExprEvaluate($rule['formula']); - } catch (Exception $e) { - $this->storeError( - sprintf( - __('Failed calculating value for rule \'%s\'.'), - $rule['name'] - ), - $e - ); - continue; - } - - $this->variables['value'] = $value; - - try { - if ($this->ruleExprEvaluate($rule['test'])) { - $this->addRule('fired', $rule); - } else { - $this->addRule('notfired', $rule); - } - } catch (Exception $e) { - $this->storeError( - sprintf( - __('Failed running test for rule \'%s\'.'), - $rule['name'] - ), - $e - ); - } - } - } - - return true; - } - - /** - * Escapes percent string to be used in format string. - * - * @param string $str string to escape - * - * @return string - */ - public static function escapePercent(string $str): string - { - return preg_replace('/%( |,|\.|$|\(|\)|<|>)/', '%%\1', $str); - } - - /** - * Wrapper function for translating. - * - * @param string $str the string - * @param string $param the parameters - * - * @return string - * @throws Exception - */ - public function translate(string $str, ?string $param = null): string - { - $string = _gettext(self::escapePercent($str)); - if ($param !== null) { - $params = $this->ruleExprEvaluate('[' . $param . ']'); - } else { - $params = []; - } - return vsprintf($string, $params); - } - - /** - * Splits justification to text and formula. - * - * @param array $rule the rule - * - * @return string[] - */ - public static function splitJustification(array $rule): array - { - $jst = preg_split('/\s*\|\s*/', $rule['justification'], 2); - if (count($jst) > 1) { - return [ - $jst[0], - $jst[1], - ]; - } - return [$rule['justification']]; - } - - /** - * Adds a rule to the result list - * - * @param string $type type of rule - * @param array $rule rule itself - * - * @return void - * @throws Exception - */ - public function addRule(string $type, array $rule): void - { - switch ($type) { - case 'notfired': - case 'fired': - $jst = self::splitJustification($rule); - if (count($jst) > 1) { - try { - /* Translate */ - $str = $this->translate($jst[0], $jst[1]); - } catch (Exception $e) { - $this->storeError( - sprintf( - __('Failed formatting string for rule \'%s\'.'), - $rule['name'] - ), - $e - ); - return; - } - - $rule['justification'] = $str; - } else { - $rule['justification'] = $this->translate($rule['justification']); - } - $rule['id'] = $rule['name']; - $rule['name'] = $this->translate($rule['name']); - $rule['issue'] = $this->translate($rule['issue']); - - // Replaces {server_variable} with 'server_variable' - // linking to server_variables.php - $rule['recommendation'] = preg_replace_callback( - '/\{([a-z_0-9]+)\}/Ui', - [ - $this, - 'replaceVariable', - ], - $this->translate($rule['recommendation']) - ); - - // Replaces external Links with Core::linkURL() generated links - $rule['recommendation'] = preg_replace_callback( - '#href=("|\')(https?://[^\1]+)\1#i', - [ - $this, - 'replaceLinkURL', - ], - $rule['recommendation'] - ); - break; - } - - $this->runResult[$type][] = $rule; - } - - /** - * Defines the rules files to use - * - * @return array - */ - protected function defineRulesFiles(): array - { - $isMariaDB = false !== strpos($this->getVariables()['version'], 'MariaDB'); - $ruleFiles = [self::GENERIC_RULES_FILE]; - // If MariaDB (= not MySQL) OR MYSQL < 8.0.3, add another rules file. - if ($isMariaDB || $this->globals['PMA_MYSQL_INT_VERSION'] < 80003) { - $ruleFiles[] = self::BEFORE_MYSQL80003_RULES_FILE; - } - return $ruleFiles; - } - - /** - * Callback for wrapping links with Core::linkURL - * - * @param array $matches List of matched elements form preg_replace_callback - * - * @return string Replacement value - */ - private function replaceLinkURL(array $matches): string - { - return 'href="' . Core::linkURL($matches[2]) . '" target="_blank" rel="noopener noreferrer"'; - } - - /** - * Callback for wrapping variable edit links - * - * @param array $matches List of matched elements form preg_replace_callback - * - * @return string Replacement value - */ - private function replaceVariable(array $matches): string - { - return '<a href="server_variables.php' . Url::getCommon(['filter' => $matches[1]]) - . '">' . htmlspecialchars($matches[1]) . '</a>'; - } - - /** - * Runs a code expression, replacing variable names with their respective - * values - * - * @param string $expr expression to evaluate - * - * @return mixed result of evaluated expression - * - * @throws Exception - */ - public function ruleExprEvaluate(string $expr) - { - // Actually evaluate the code - // This can throw exception - $value = $this->expression->evaluate( - $expr, - array_merge($this->variables, $this->globals) - ); - - return $value; - } - - /** - * Reads the rule file into an array, throwing errors messages on syntax - * errors. - * - * @param string $filename Name of file to parse - * - * @return array with parsed data - */ - public static function parseRulesFile(string $filename): array - { - $file = file($filename, FILE_IGNORE_NEW_LINES); - - $errors = []; - $rules = []; - $lines = []; - - if ($file === false) { - $errors[] = sprintf( - __('Error in reading file: The file \'%s\' does not exist or is not readable!'), - $filename - ); - return [ - 'rules' => $rules, - 'lines' => $lines, - 'errors' => $errors, - ]; - } - - $ruleSyntax = [ - 'name', - 'formula', - 'test', - 'issue', - 'recommendation', - 'justification', - ]; - $numRules = count($ruleSyntax); - $numLines = count($file); - $ruleNo = -1; - $ruleLine = -1; - - for ($i = 0; $i < $numLines; $i++) { - $line = $file[$i]; - if ($line == "" || $line[0] == '#') { - continue; - } - - // Reading new rule - if (substr($line, 0, 4) == 'rule') { - if ($ruleLine > 0) { - $errors[] = sprintf( - __( - 'Invalid rule declaration on line %1$s, expected line ' - . '%2$s of previous rule.' - ), - $i + 1, - $ruleSyntax[$ruleLine++] - ); - continue; - } - if (preg_match("/rule\s'(.*)'( \[(.*)\])?$/", $line, $match)) { - $ruleLine = 1; - $ruleNo++; - $rules[$ruleNo] = ['name' => $match[1]]; - $lines[$ruleNo] = ['name' => $i + 1]; - if (isset($match[3])) { - $rules[$ruleNo]['precondition'] = $match[3]; - $lines[$ruleNo]['precondition'] = $i + 1; - } - } else { - $errors[] = sprintf( - __('Invalid rule declaration on line %s.'), - $i + 1 - ); - } - continue; - } elseif ($ruleLine == -1) { - $errors[] = sprintf( - __('Unexpected characters on line %s.'), - $i + 1 - ); - } - - // Reading rule lines - if ($ruleLine > 0) { - if (! isset($line[0])) { - continue; // Empty lines are ok - } - // Non tabbed lines are not - if ($line[0] != "\t") { - $errors[] = sprintf( - __( - 'Unexpected character on line %1$s. Expected tab, but ' - . 'found "%2$s".' - ), - $i + 1, - $line[0] - ); - continue; - } - $rules[$ruleNo][$ruleSyntax[$ruleLine]] = rtrim( - mb_substr($line, 1) - ); - $lines[$ruleNo][$ruleSyntax[$ruleLine]] = $i + 1; - ++$ruleLine; - } - - // Rule complete - if ($ruleLine == $numRules) { - $ruleLine = -1; - } - } - - return [ - 'rules' => $rules, - 'lines' => $lines, - 'errors' => $errors, - ]; - } - - /** - * Formats interval like 10 per hour - * - * @param float $num number to format - * @param integer $precision required precision - * - * @return string formatted string - */ - public static function byTime(float $num, int $precision): string - { - if ($num >= 1) { // per second - $per = __('per second'); - } elseif ($num * 60 >= 1) { // per minute - $num *= 60; - $per = __('per minute'); - } elseif ($num * 60 * 60 >= 1) { // per hour - $num = $num * 60 * 60; - $per = __('per hour'); - } else { - $num = $num * 60 * 60 * 24; - $per = __('per day'); - } - - $num = round($num, $precision); - - if ($num == 0) { - $num = '<' . pow(10, -$precision); - } - - return "$num $per"; - } - - /** - * Wrapper for PhpMyAdmin\Util::timespanFormat - * - * This function is used when evaluating advisory_rules.txt - * - * @param int $seconds the timespan - * - * @return string the formatted value - */ - public static function timespanFormat(int $seconds): string - { - return Util::timespanFormat($seconds); - } - - /** - * Wrapper around PhpMyAdmin\Util::formatByteDown - * - * This function is used when evaluating advisory_rules.txt - * - * @param double|string $value the value to format - * @param int $limes the sensitiveness - * @param int $comma the number of decimals to retain - * - * @return string the formatted value with unit - */ - public static function formatByteDown($value, int $limes = 6, int $comma = 0): string - { - return implode(' ', Util::formatByteDown($value, $limes, $comma)); - } -} |
