<?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 */ namespace PMA\libraries; use \Exception; require_once 'libraries/advisor.lib.php'; /** * Advisor class * * @package PhpMyAdmin */ class Advisor { protected $variables; protected $parseResult; protected $runResult; /** * Get variables * * @return mixed */ public function getVariables() { return $this->variables; } /** * Set variables * * @param array $variables Variables * * @return Advisor */ public function setVariables($variables) { $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 $this */ public function setVariable($variable, $value) { $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($parseResult) { $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($runResult) { $this->runResult = $runResult; return $this; } /** * Parses and executes advisor rules * * @return array with run and parse results */ public function run() { // HowTo: A simple Advisory system in 3 easy steps. // Step 1: Get some variables to evaluate on $this->setVariables( array_merge( $GLOBALS['dbi']->fetchResult('SHOW GLOBAL STATUS', 0, 1), $GLOBALS['dbi']->fetchResult('SHOW GLOBAL VARIABLES', 0, 1) ) ); // Add total memory to variables as well include_once 'libraries/sysinfo.lib.php'; $sysinfo = PMA_getSysInfo(); $memory = $sysinfo->memory(); $this->variables['system_memory'] = isset($memory['MemTotal']) ? $memory['MemTotal'] : 0; // Step 2: Read and parse the list of rules $this->setParseResult(static::parseRulesFile()); // Step 3: Feed the variables to the rules and let them fire. Sets // $runResult $this->runRules(); return array( 'parse' => array('errors' => $this->parseResult['errors']), 'run' => $this->runResult ); } /** * Stores current error in run results. * * @param string $description description of an error. * @param Exception $exception exception raised * * @return void */ public function storeError($description, $exception) { $this->runResult['errors'][] = $description . ' ' . sprintf( __('PHP threw following error: %s'), $exception->getMessage() ); } /** * Executes advisor rules * * @return boolean */ public function runRules() { $this->setRunResult( array( 'fired' => array(), 'notfired' => array(), 'unchecked' => array(), 'errors' => array(), ) ); 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($str) { return preg_replace('/%( |,|\.|$|\(|\)|<|>)/', '%%\1', $str); } /** * Wrapper function for translating. * * @param string $str the string * @param string $param the parameters * * @return string */ public function translate($str, $param = null) { $string = _gettext(self::escapePercent($str)); if (! is_null($param)) { $params = $this->ruleExprEvaluate('array(' . $param . ')'); } else { $params = array(); } return vsprintf($string, $params); } /** * Splits justification to text and formula. * * @param array $rule the rule * * @return string[] */ public static function splitJustification($rule) { $jst = preg_split('/\s*\|\s*/', $rule['justification'], 2); if (count($jst) > 1) { return array($jst[0], $jst[1]); } return array($rule['justification']); } /** * Adds a rule to the result list * * @param string $type type of rule * @param array $rule rule itself * * @return void */ public function addRule($type, $rule) { 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( '/\{([a-z_0-9]+)\}/Ui', '<a href="server_variables.php' . PMA_URL_getCommon() . '&filter=\1">\1</a>', $this->translate($rule['recommendation']) ); // Replaces external Links with PMA_linkURL() generated links $rule['recommendation'] = preg_replace_callback( '#href=("|\')(https?://[^\1]+)\1#i', array($this, 'replaceLinkURL'), $rule['recommendation'] ); break; } $this->runResult[$type][] = $rule; } /** * Callback for wrapping links with PMA_linkURL * * @param array $matches List of matched elements form preg_replace_callback * * @return string Replacement value */ private function replaceLinkURL($matches) { return 'href="' . PMA_linkURL($matches[2]) . '" target="_blank" rel="noopener noreferrer"'; } /** * Callback for evaluating fired() condition. * * @param array $matches List of matched elements form preg_replace_callback * * @return string Replacement value */ private function ruleExprEvaluateFired($matches) { // No list of fired rules if (!isset($this->runResult['fired'])) { return '0'; } // Did matching rule fire? foreach ($this->runResult['fired'] as $rule) { if ($rule['id'] == $matches[2]) { return '1'; } } return '0'; } /** * Callback for evaluating variables in expression. * * @param array $matches List of matched elements form preg_replace_callback * * @return string Replacement value */ private function ruleExprEvaluateVariable($matches) { if (! isset($this->variables[$matches[1]])) { return $matches[1]; } if (is_numeric($this->variables[$matches[1]])) { return $this->variables[$matches[1]]; } else { return '\'' . addslashes($this->variables[$matches[1]]) . '\''; } } /** * Runs a code expression, replacing variable names with their respective * values * * @param string $expr expression to evaluate * * @return integer result of evaluated expression * * @throws Exception */ public function ruleExprEvaluate($expr) { // Evaluate fired() conditions $expr = preg_replace_callback( '/fired\s*\(\s*(\'|")(.*)\1\s*\)/Ui', array($this, 'ruleExprEvaluateFired'), $expr ); // Evaluate variables $expr = preg_replace_callback( '/\b(\w+)\b/', array($this, 'ruleExprEvaluateVariable'), $expr ); $value = 0; $err = 0; // Actually evaluate the code ob_start(); try { eval('$value = ' . $expr . ';'); $err = ob_get_contents(); } catch (Exception $e) { // In normal operation, there is just output in the buffer, // but when running under phpunit, error in eval raises exception $err = $e->getMessage(); } ob_end_clean(); // Error handling if ($err) { throw new Exception( strip_tags($err) . '<br />Executed code: $value = ' . htmlspecialchars($expr) . ';' ); } return $value; } /** * Reads the rule file into an array, throwing errors messages on syntax * errors. * * @return array with parsed data */ public static function parseRulesFile() { $filename = 'libraries/advisory_rules.txt'; $file = file($filename, FILE_IGNORE_NEW_LINES); $errors = array(); $rules = array(); $lines = array(); if ($file === FALSE) { $errors[] = sprintf( __('Error in reading file: The file \'%s\' does not exist or is not readable!'), $filename ); return array('rules' => $rules, 'lines' => $lines, 'errors' => $errors); } $ruleSyntax = array( '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] = array('name' => $match[1]); $lines[$ruleNo] = array('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; } else { if ($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]] = chop( mb_substr($line, 1) ); $lines[$ruleNo][$ruleSyntax[$ruleLine]] = $i + 1; ++$ruleLine; } // Rule complete if ($ruleLine == $numRules) { $ruleLine = -1; } } return array('rules' => $rules, 'lines' => $lines, 'errors' => $errors); } }
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
bfShapeFiles | Folder | 0755 |
|
|
config | Folder | 0755 |
|
|
controllers | Folder | 0755 |
|
|
dbi | Folder | 0755 |
|
|
di | Folder | 0755 |
|
|
engines | Folder | 0755 |
|
|
gis | Folder | 0755 |
|
|
navigation | Folder | 0755 |
|
|
plugins | Folder | 0755 |
|
|
properties | Folder | 0755 |
|
|
rte | Folder | 0755 |
|
|
sql-parser | Folder | 0755 |
|
|
Advisor.php | File | 15.13 KB | 0644 |
|
Config.php | File | 54.7 KB | 0644 |
|
Console.php | File | 14.82 KB | 0644 |
|
DatabaseInterface.php | File | 95.6 KB | 0644 |
|
DbList.php | File | 1.9 KB | 0644 |
|
DbQbe.php | File | 68.87 KB | 0644 |
|
DbSearch.php | File | 17.21 KB | 0644 |
|
DisplayResults.php | File | 206 KB | 0644 |
|
Error.php | File | 12.7 KB | 0644 |
|
ErrorHandler.php | File | 16.48 KB | 0644 |
|
File.php | File | 18.82 KB | 0644 |
|
Font.php | File | 4.24 KB | 0644 |
|
Footer.php | File | 10.52 KB | 0644 |
|
Header.php | File | 25.34 KB | 0644 |
|
Index.php | File | 23.79 KB | 0644 |
|
IndexColumn.php | File | 4.46 KB | 0644 |
|
Language.php | File | 4.27 KB | 0644 |
|
LanguageManager.php | File | 20.75 KB | 0644 |
|
Linter.php | File | 5.02 KB | 0644 |
|
ListAbstract.php | File | 3.15 KB | 0644 |
|
ListDatabase.php | File | 4.62 KB | 0644 |
|
Menu.php | File | 21.14 KB | 0644 |
|
Message.php | File | 18.67 KB | 0644 |
|
OutputBuffering.php | File | 3.59 KB | 0644 |
|
PDF.php | File | 3.94 KB | 0644 |
|
Partition.php | File | 7.26 KB | 0644 |
|
Psr4Autoloader.php | File | 4.85 KB | 0644 |
|
RecentFavoriteTable.php | File | 11.78 KB | 0644 |
|
Response.php | File | 12.61 KB | 0644 |
|
SavedSearches.php | File | 11.67 KB | 0644 |
|
Scripts.php | File | 7.38 KB | 0644 |
|
ServerStatusData.php | File | 15.72 KB | 0644 |
|
StorageEngine.php | File | 13.61 KB | 0644 |
|
SubPartition.php | File | 3.52 KB | 0644 |
|
SysInfo.php | File | 799 B | 0644 |
|
SysInfoLinux.php | File | 1.92 KB | 0644 |
|
SysInfoSunOS.php | File | 1.86 KB | 0644 |
|
SysInfoWINNT.php | File | 3.08 KB | 0644 |
|
SystemDatabase.php | File | 3.66 KB | 0644 |
|
Table.php | File | 88.12 KB | 0644 |
|
Template.php | File | 4.45 KB | 0644 |
|
Theme.php | File | 11.34 KB | 0644 |
|
ThemeManager.php | File | 12.91 KB | 0644 |
|
Tracker.php | File | 30.35 KB | 0644 |
|
Types.php | File | 6.08 KB | 0644 |
|
TypesMySQL.php | File | 17.26 KB | 0644 |
|
Util.php | File | 172.46 KB | 0644 |
|
VersionInformation.php | File | 7.87 KB | 0644 |
|
ZipFile.php | File | 6.63 KB | 0644 |
|
advisor.lib.php | File | 1.6 KB | 0644 |
|
advisory_rules.txt | File | 25.94 KB | 0644 |
|
autoloader.php | File | 450 B | 0644 |
|
bookmark.lib.php | File | 8.5 KB | 0644 |
|
browse_foreigners.lib.php | File | 9.83 KB | 0644 |
|
central_columns.lib.php | File | 49.38 KB | 0644 |
|
charset_conversion.lib.php | File | 3.54 KB | 0644 |
|
check_user_privileges.lib.php | File | 10.65 KB | 0644 |
|
cleanup.lib.php | File | 1.29 KB | 0644 |
|
common.inc.php | File | 34.38 KB | 0644 |
|
config.default.php | File | 66.5 KB | 0644 |
|
config.values.php | File | 10.17 KB | 0644 |
|
core.lib.php | File | 29.94 KB | 0644 |
|
create_addfield.lib.php | File | 15.68 KB | 0644 |
|
database_interface.inc.php | File | 2.63 KB | 0644 |
|
db_common.inc.php | File | 3.12 KB | 0644 |
|
db_designer.lib.php | File | 10.4 KB | 0644 |
|
db_table_exists.lib.php | File | 3.21 KB | 0644 |
|
display_change_password.lib.php | File | 5.45 KB | 0644 |
|
display_create_table.lib.php | File | 1.53 KB | 0644 |
|
display_export.lib.php | File | 38.11 KB | 0644 |
|
display_git_revision.lib.php | File | 3.04 KB | 0644 |
|
display_import.lib.php | File | 24.34 KB | 0644 |
|
display_import_ajax.lib.php | File | 3.13 KB | 0644 |
|
display_select_lang.lib.php | File | 2.36 KB | 0644 |
|
error.inc.php | File | 1.21 KB | 0644 |
|
error_report.lib.php | File | 10.25 KB | 0644 |
|
export.lib.php | File | 35.16 KB | 0644 |
|
file_listing.lib.php | File | 2.37 KB | 0644 |
|
iconv_wrapper.lib.php | File | 3.88 KB | 0644 |
|
import.lib.php | File | 50.64 KB | 0644 |
|
index.lib.php | File | 1.37 KB | 0644 |
|
information_schema_relations.lib.php | File | 10.95 KB | 0644 |
|
insert_edit.lib.php | File | 112.79 KB | 0644 |
|
ip_allow_deny.lib.php | File | 9.35 KB | 0644 |
|
js_escape.lib.php | File | 4.43 KB | 0644 |
|
kanji-encoding.lib.php | File | 4.46 KB | 0644 |
|
language_stats.inc.php | File | 1.45 KB | 0644 |
|
logging.lib.php | File | 521 B | 0644 |
|
mime.lib.php | File | 704 B | 0644 |
|
mult_submits.inc.php | File | 10.64 KB | 0644 |
|
mult_submits.lib.php | File | 20.44 KB | 0644 |
|
mysql_charsets.inc.php | File | 4.09 KB | 0644 |
|
mysql_charsets.lib.php | File | 10.47 KB | 0644 |
|
mysql_relations.lib.php | File | 5.12 KB | 0644 |
|
normalization.lib.php | File | 33.98 KB | 0644 |
|
opendocument.lib.php | File | 7.94 KB | 0644 |
|
operations.lib.php | File | 73.64 KB | 0644 |
|
parse_analyze.lib.php | File | 2.12 KB | 0644 |
|
plugin_interface.lib.php | File | 19.69 KB | 0644 |
|
plugin_interface.lib.php.bak | File | 19.69 KB | 0644 |
|
pmd_common.php | File | 24.2 KB | 0644 |
|
relation.lib.php | File | 68.41 KB | 0644 |
|
relation_cleanup.lib.php | File | 13.84 KB | 0644 |
|
replication.inc.php | File | 8.82 KB | 0644 |
|
replication_gui.lib.php | File | 37.45 KB | 0644 |
|
sanitizing.lib.php | File | 6.3 KB | 0644 |
|
select_server.lib.php | File | 3.4 KB | 0644 |
|
server_common.inc.php | File | 1.22 KB | 0644 |
|
server_common.lib.php | File | 1.92 KB | 0644 |
|
server_privileges.lib.php | File | 179.22 KB | 0644 |
|
server_status.lib.php | File | 9.92 KB | 0644 |
|
server_status_advisor.lib.php | File | 1.89 KB | 0644 |
|
server_status_monitor.lib.php | File | 26.22 KB | 0644 |
|
server_status_processes.lib.php | File | 9.57 KB | 0644 |
|
server_status_queries.lib.php | File | 4.86 KB | 0644 |
|
server_status_variables.lib.php | File | 28.95 KB | 0644 |
|
server_user_groups.lib.php | File | 12.8 KB | 0644 |
|
server_users.lib.php | File | 1.35 KB | 0644 |
|
session.inc.php | File | 5.22 KB | 0644 |
|
session.lib.php | File | 735 B | 0644 |
|
special_schema_links.lib.php | File | 17.51 KB | 0644 |
|
sql.lib.php | File | 77.51 KB | 0644 |
|
sql.lib.php.bak | File | 77.51 KB | 0644 |
|
sql_query_form.lib.php | File | 15.71 KB | 0644 |
|
string.lib.php | File | 800 B | 0644 |
|
stringMb.lib.php | File | 1.86 KB | 0644 |
|
stringNative.lib.php | File | 6.82 KB | 0644 |
|
sysinfo.lib.php | File | 1.34 KB | 0644 |
|
tbl_columns_definition_form.inc.php | File | 13.55 KB | 0644 |
|
tbl_common.inc.php | File | 1.3 KB | 0644 |
|
tbl_info.inc.php | File | 3.54 KB | 0644 |
|
tbl_partition_definition.inc.php | File | 5.55 KB | 0644 |
|
tracking.lib.php | File | 54.93 KB | 0644 |
|
transformations.lib.php | File | 14.63 KB | 0644 |
|
url_generating.lib.php | File | 6.77 KB | 0644 |
|
user_preferences.inc.php | File | 2.38 KB | 0644 |
|
user_preferences.lib.php | File | 8.17 KB | 0644 |
|
util.lib.php | File | 749 B | 0644 |
|
vendor_config.php | File | 2.49 KB | 0644 |
|
zip_extension.lib.php | File | 5.38 KB | 0644 |
|