public function generate($folder, $name = null) { $list = Analyzer::getThemeAnalyzers($this->themesToShow); $list = '"' . join('", "', $list) . '"'; $sqlite = new \Sqlite3($folder . '/dump.sqlite'); $sqlQuery = 'SELECT * FROM results WHERE analyzer in (' . $list . ')'; $res = $sqlite->query($sqlQuery); $results = array(); $titleCache = array(); $severityCache = array(); while ($row = $res->fetchArray(SQLITE3_ASSOC)) { if (!isset($results[$row['file']])) { $file = array('errors' => 0, 'warnings' => 0, 'fixable' => 0, 'filename' => $row['file'], 'messages' => array()); $results[$row['file']] = $file; } if (!isset($titleCache[$row['analyzer']])) { $analyzer = Analyzer::getInstance($row['analyzer']); $titleCache[$row['analyzer']] = $analyzer->getDescription()->getName(); $severityCache[$row['analyzer']] = $analyzer->getSeverity(); } $message = array('type' => 'warning', 'source' => $row['analyzer'], 'severity' => $severityCache[$row['analyzer']], 'fixable' => 'fixable', 'message' => $titleCache[$row['analyzer']]); if (!isset($results[$row['file']]['messages'][$row['line']])) { $results[$row['file']]['messages'][$row['line']] = array(0 => array()); } $results[$row['file']]['messages'][$row['line']][0][] = $message; ++$results[$row['file']]['warnings']; $this->count(); } if ($name === null) { return json_encode($results); } else { file_put_contents($folder . '/' . $name . '.' . self::FILE_EXTENSION, json_encode($results)); return true; } }
public function run() { $project = 'test'; // Check for requested file if (!empty($this->config->filename) && !file_exists($this->config->filename)) { throw new NoSuchFile($this->config->filename); } elseif (!empty($this->config->dirname) && !file_exists($this->config->dirname)) { throw new NoSuchDir($this->config->filename); } // Check for requested analyze $analyzer = $this->config->program; if (Analyzer::getClass($analyzer)) { $analyzers_class = array($analyzer); } else { $r = Analyzer::getSuggestionClass($analyzer); if (count($r) > 0) { echo 'did you mean : ', implode(', ', str_replace('_', '/', $r)), "\n"; } throw new NoSuchAnalyzer($analyzer); } display("Cleaning DB\n"); $clean = new CleanDb($this->gremlin, $this->config, Tasks::IS_SUBTASK); $clean->run(); $load = new Load($this->gremlin, $this->config, Tasks::IS_SUBTASK); $load->run(); unset($load); display("Project loaded\n"); $analyze = new Analyze($this->gremlin, $this->config, Tasks::IS_SUBTASK); $analyze->run(); unset($analyze); $results = new Results($this->gremlin, $this->config, Tasks::IS_SUBTASK); $results->run(); unset($results); display("Analyzed project\n"); }
public function generate($folder, $name = null) { $sqlite = new \Sqlite3($folder . '/dump.sqlite'); $sqlQuery = 'SELECT * FROM results WHERE analyzer in ' . $this->themesList; $res = $sqlite->query($sqlQuery); $results = array(); $titleCache = array(); $severityCache = array(); $results = array(); while ($row = $res->fetchArray(SQLITE3_ASSOC)) { if (!isset($titleCache[$row['analyzer']])) { $analyzer = Analyzer::getInstance($row['analyzer']); $titleCache[$row['analyzer']] = $analyzer->getDescription()->getName(); $severityCache[$row['analyzer']] = $analyzer->getSeverity(); $clearphp = $analyzer->getDescription()->getClearPHP(); } else { $clearphp = ''; } $message = array('code' => $row['fullcode'], 'line' => $row['line'], 'clearphp' => $clearphp); if (!isset($results[$titleCache[$row['analyzer']]])) { $results[$titleCache[$row['analyzer']]] = array(); } $results[$titleCache[$row['analyzer']]][] = $message; $this->count(); } if ($name === null) { return json_encode($results); } else { file_put_contents($folder . '/' . $name . '.' . self::FILE_EXTENSION, json_encode($results)); return true; } }
public function __construct() { $this->config = Config::factory(); $analyzers = Analyzer::getThemeAnalyzers($this->config->thema); $this->themesList = '("' . implode('", "', $analyzers) . '")'; $this->sqlite = new \Sqlite3($this->config->projects_root . '/projects/' . $this->config->project . '/dump.sqlite', \SQLITE3_OPEN_READONLY); $this->datastore = new Datastore($this->config); }
public function hasResults() { Analyzer::initDocs(); $data = Analyzer::$datastore->getRow('composer'); $this->report = array(); foreach ($data as $d) { $this->report[$d['component'] . ' (' . $d['version'] . ')'] = true; } return count($this->report) > 0; }
public function run() { $result = new \Stdclass(); $analyzers = Analyzer::getThemeAnalyzers('OneFile'); foreach ($analyzers as $analyzer) { $a = Analyzer::getInstance($analyzer); $results = $a->getArray(); if (!empty($results)) { $result->{$a->getDescription()->getName()} = $results; } } file_put_contents($this->config->projects_root . '/projects/' . $project . '/onepage.json', json_encode($result)); }
public function generate($folder, $name = 'txt') { $config = Config::factory(); $themes = $config->thema; $analyzers = array(); foreach ($themes as $theme) { $analyzers[] = Analyzer::getThemeAnalyzers($theme); } $analyzers = call_user_func_array('array_merge', $analyzers); display(count($analyzers) . " analyzers\n"); $res = $this->sqlite->query('SELECT distinct analyzer FROM results WHERE analyzer IN ("' . implode('","', $analyzers) . '") ORDER BY analyzer'); $skeleton = array(); while ($row = $res->fetchArray(SQLITE3_ASSOC)) { $skeleton[$row['analyzer']] = 0; } display(count($skeleton) . " distinct analyzers\n"); $titles = array(); foreach ($skeleton as $analyzer => $foo) { if ($analyzer == 'total') { continue; } $ini = parse_ini_file($this->config->dir_root . '/human/en/' . $analyzer . '.ini'); $titles[$analyzer] = '"' . $ini['name'] . '"'; } $all = array(); $res = $this->sqlite->query('SELECT * FROM results WHERE analyzer IN ("' . implode('","', $analyzers) . '") ORDER BY file'); $total = 0; while ($row = $res->fetchArray(SQLITE3_ASSOC)) { if (!isset($all[$row['file']])) { $all[$row['file']] = $skeleton; } ++$all[$row['file']][$row['analyzer']]; ++$total; } display($total . " issues read\n"); $txt = " \t" . implode("\t", array_values($titles)) . "\n"; foreach ($all as $file => $values) { $txt .= "{$file}\t" . implode("\t", array_values($values)) . "\n"; } file_put_contents($folder . '/' . $name . '.' . self::FILE_EXTENSION, $txt); display(count($all) . " issues reported\n"); print "Upload " . $name . '.' . self::FILE_EXTENSION . " on http://amp.pharm.mssm.edu/clustergrammer/\n"; }
public function generate($dirName, $fileName = null) { $sqlite = new \sqlite3($dirName . '/dump.sqlite', \SQLITE3_OPEN_READONLY); $sqlQuery = <<<SQL SELECT id AS id, fullcode AS code, file AS file, line AS line, analyzer AS analyzer FROM results WHERE analyzer IN {$this->themesList} SQL; $res = $sqlite->query($sqlQuery); $config = Config::factory(); $datastore = new Datastore($config); $items = array(); while ($row = $res->fetchArray(SQLITE3_ASSOC)) { $ini = parse_ini_file($config->dir_root . '/human/en/' . $row['analyzer'] . '.ini'); $row['error'] = $ini['name']; $a = Analyzer::getInstance($row['analyzer']); $row['severity'] = $a->getSeverity(); $row['impact'] = $a->getTimeToFix(); $row['recipes'] = $a->getThemes(); $items[] = $row; $this->count(); } if ($fileName === null) { $json = json_encode($items, JSON_PARTIAL_OUTPUT_ON_ERROR); // @todo Log if $json == false return $json; } else { file_put_contents($dirName . '/' . $fileName . '.' . self::FILE_EXTENSION, json_encode($items)); return true; } }
public function getTimeToFix() { if (Analyzer::$docs === null) { $config = Config::factory(); Analyzer::$docs = new Docs($config->dir_root . '/data/analyzers.sqlite'); } return Analyzer::$docs->getTimeToFix($this->analyzer); }
public function run() { $analyzer = $this->config->program; if (empty($analyzer)) { die('Provide the analyzer with the option -P X/Y. Aborting' . "\n"); } $analyzerClass = Analyzer::getClass($analyzer); if ($analyzerClass === false) { $die = "'{$analyzer}' doesn't exist. Aborting\n"; $r = Analyzer::getSuggestionClass($analyzer); if (count($r) > 0) { $die .= 'Did you mean : ' . implode(', ', str_replace('_', '/', $r)) . "\n"; } die($die); } $analyzer = Analyzer::getName($analyzerClass); $query = <<<GREMLIN g.V().hasLabel("Analysis").has("analyzer", "{$analyzer}").out().count(); GREMLIN; $vertices = $this->gremlin->query($query)->results; if (isset($vertices[0]->notCompatibleWithPhpVersion)) { die($this->config->program . " is not compatible with the running version of PHP. No result available.\n"); } if (isset($vertices[0]->notCompatibleWithPhpConfiguration)) { die($this->config->program . " is not compatible with the compilation of the running version of PHP. No result available.\n"); } $return = array(); if ($this->config->style == 'BOOLEAN') { $queryTemplate = 'g.V().hasLabel("Analysis").has("analyzer", "' . $analyzer . '").out().count().is(gt(0))'; $vertices = $this->gremlin->query($queryTemplate); $return[] = $vertices[0]; } elseif ($this->config->style == 'COUNTED_ALL') { $queryTemplate = 'g.V().hasLabel("Analysis").has("analyzer", "' . $analyzer . '").out().count()'; $vertices = $this->gremlin->query($queryTemplate)->results; $return[] = $vertices[0]; } elseif ($this->config->style == 'ALL') { $linksDown = Token::linksAsList(); $query = <<<GREMLIN g.V().hasLabel("Analysis").has("analyzer", "{$analyzer}").out('ANALYZED') .sideEffect{ line = it.get().value('line'); fullcode = it.get().value('fullcode'); file='None'; theFunction = 'None'; theClass='None'; theNamespace='None'; } .sideEffect{ line = it.get().value('line'); } .until( hasLabel('Project') ).repeat( __.in({$linksDown}) .sideEffect{ if (it.get().label() == 'Function') { theFunction = it.get().value('code')} } .sideEffect{ if (it.get().label() == 'Class') { theClass = it.get().value('fullcode')} } .sideEffect{ if (it.get().label() == 'File') { file = it.get().value('fullcode')} } ) .map{ ['line':line, 'file':file, 'fullcode':fullcode, 'function':theFunction, 'class':theClass, 'namespace':theNamespace]; } GREMLIN; $vertices = $this->gremlin->query($query)->results; $return = array(); foreach ($vertices as $k => $v) { $row = array($v->fullcode, $v->file, $v->line, $v->namespace, $v->class, $v->function); $return[] = $row; } } elseif ($this->config->style == 'DISTINCT') { $queryTemplate = 'g.V().hasLabel("Analysis").has("analyzer", "' . $analyzer . '").out("ANALYZED").values("code").unique()'; $vertices = $this->gremlin->query($queryTemplate)->results; $return = array(); foreach ($vertices as $k => $v) { $return[] = array($v); } } elseif ($this->config->style == 'COUNTED') { $queryTemplate = 'g.V().hasLabel("Analysis").has("analyzer", "' . $analyzer . '").out("ANALYZED").groupCount("m")by("code").cap("m")'; $vertices = $this->gremlin->query($queryTemplate)->results; $return = array(); foreach ($vertices[0] as $k => $v) { $return[$k] = $v; } } if ($this->config->json === true) { $text = json_encode($return); } elseif ($this->config->csv === true) { $text = array(array('Code', 'File', 'Namespace', 'Class', 'Function')); foreach ($return as $k => $v) { if (is_array($v)) { $text[] = $v; } else { $text[] = array($k, $v); } } } elseif ($this->config->html === true || $this->config->odt === true) { $text = ''; foreach ($return as $k => $r) { if ($this->config->style == 'COUNTED') { $text .= "+ {$k} => {$r}\n"; } else { $text .= "+ {$k}\n"; if (is_array($r)) { $text .= ' + ' . implode("\n + ", $r) . "\n"; } else { $text .= "+ {$r}\n"; } } } } else { // count also for $this->config->text == 1 $text = ''; foreach ($return as $k => $v) { if ($this->config->style == 'COUNTED') { $text .= "{$k} => {$v}\n"; } else { $text .= implode(', ', $v) . "\n"; } } } if ($this->config->output) { echo $text; } switch (1) { case $this->config->json: $extension = 'json'; break 1; case $this->config->odt: $extension = 'odt'; break 1; case $this->config->html: $extension = 'html'; break 1; case $this->config->csv: $extension = 'csv'; break 1; case $this->config->text: default: $extension = 'txt'; break 1; } if ($this->config->file != 'stdout') { $name = $this->config->file . '.' . $extension; if (file_exists($name)) { die("{$name} already exists. Aborting\n"); } if ($this->config->format == 'ODT') { $name1 = FILE . '.html'; file_put_contents($name1, $text); $name = FILE . '.' . $extension; shell_exec('pandoc -o ' . $name . ' ' . $name1); unlink($name1); } elseif ($this->config->format == 'CSV') { $csvFile = fopen($name, 'w'); foreach ($text as $t) { fputcsv($csvFile, $t); } fclose($csvFile); } else { file_put_contents($name, $text); } } }
private function generateAppinfo() { $extensions = array('PHP' => array('Short tags' => 'Structures/ShortTags', 'Echo tags <?=' => 'Php/EchoTagUsage', 'Incompilable' => 'Php/Incompilable', '@ operator' => 'Structures/Noscream', 'Alternative syntax' => 'Php/AlternativeSyntax', 'Magic constants' => 'Constants/MagicConstantUsage', 'halt compiler' => 'Php/Haltcompiler', 'Assertions' => 'Php/AssertionUsage', 'Casting' => 'Php/CastingUsage', 'Resources' => 'Structures/ResourcesUsage', 'Nested Loops' => 'Structures/NestedLoops', 'Autoload' => 'Php/AutoloadUsage', 'inclusion' => 'Structures/IncludeUsage', 'include_once' => 'Structures/OnceUsage', 'Output control' => 'Extensions/Extob', 'Goto' => 'Php/Gotonames', 'Labels' => 'Php/Labelnames', 'Coalesce' => 'Php/Coalesce', 'Null Coalesce' => 'Php/NullCoalesce', 'File upload' => 'Structures/FileUploadUsage', 'Environnement Variables' => 'Php/UsesEnv'), 'Composer' => array('composer.json' => 'Composer/UseComposer', 'composer.lock' => 'Composer/UseComposerLock', 'composer autoload' => 'Composer/Autoload'), 'Web' => array('$_GET, _POST...' => 'Php/UseWeb', 'Apache' => 'Extensions/Extapache', 'Fast CGI' => 'Extensions/Extfpm', 'IIS' => 'Extensions/Extiis', 'NSAPI' => 'Extensions/Extnsapi'), 'CLI' => array('$argv, $argc' => 'Php/UseCli', 'CLI script' => 'Files/IsCliScript', 'Ncurses' => 'Extensions/Extncurses', 'Newt' => 'Extensions/Extnewt', 'Readline' => 'Extensions/Extreadline'), 'Composer Packages' => array(), 'Namespaces' => array('Namespaces' => 'Namespaces/Namespacesnames', 'Alias' => 'Namespaces/Alias'), 'Variables' => array('References' => 'Variables/References', 'Array' => 'Arrays/Arrayindex', 'Multidimensional arrays' => 'Arrays/Multidimensional', 'Array short syntax' => 'Arrays/ArrayNSUsage', 'List short syntax' => 'Structures/ListShortSyntax', 'Variable variables' => 'Variables/VariableVariables', 'PHP arrays' => 'Arrays/Phparrayindex', 'Globals' => 'Structures/GlobalUsage', 'PHP SuperGlobals' => 'Php/SuperGlobalUsage'), 'Functions' => array('Functions' => 'Functions/Functionnames', 'Redeclared PHP Functions' => 'Functions/RedeclaredPhpFunction', 'Closures' => 'Functions/Closures', 'Typehint' => 'Functions/Typehints', 'Scalar Typehint' => 'Php/ScalarTypehintUsage', 'Return Typehint' => 'Php/ReturnTypehintUsage', 'Nullable Typehint' => 'Php/UseNullableType', 'Static variables' => 'Variables/StaticVariables', 'Function dereferencing' => 'Structures/FunctionSubscripting', 'Constant scalar expression' => 'Structures/ConstantScalarExpression', '... usage' => 'Php/EllipsisUsage', 'func_get_args' => 'Functions/VariableArguments', 'Dynamic functioncall' => 'Functions/Dynamiccall', 'Recursive Functions' => 'Functions/Recursive', 'Generator Functions' => 'Functions/IsGenerator', 'Conditioned Function' => 'Functions/ConditionedFunctions'), 'Classes' => array('Classes' => 'Classes/Classnames', 'Anonymous Classes' => 'Classes/Anonymous', 'Class aliases' => 'Classes/ClassAliasUsage', 'Abstract classes' => 'Classes/Abstractclass', 'Interfaces' => 'Interfaces/Interfacenames', 'Traits' => 'Traits/Traitnames', 'Static properties' => 'Classes/StaticProperties', 'Static methods' => 'Classes/StaticMethods', 'Abstract methods' => 'Classes/Abstractmethods', 'Final methods' => 'Classes/Finalmethod', 'Class constants' => 'Classes/ConstantDefinition', 'Overwritten constants' => 'Classes/OverwrittenConst', 'Magic methods' => 'Classes/MagicMethod', 'Cloning' => 'Classes/CloningUsage', 'Dynamic class call' => 'Classes/VariableClasses', 'PHP 4 constructor' => 'Classes/OldStyleConstructor', 'Multiple class in one file' => 'Classes/MultipleClassesInFile'), 'Constants' => array('Constants' => 'Constants/ConstantUsage', 'Boolean' => 'Type/BooleanValue', 'Null' => 'Type/NullValue', 'Variable Constant' => 'Constants/VariableConstant', 'PHP constants' => 'Constants/PhpConstantUsage', 'PHP Magic constants' => 'Constants/MagicConstantUsage', 'Conditioned constant' => 'Constants/ConditionedConstants'), 'Numbers' => array('Integers' => 'Type/Integer', 'Hexadecimal' => 'Type/Hexadecimal', 'Octal' => 'Type/Octal', 'Binary' => 'Type/Binary', 'Real' => 'Type/Real'), 'Strings' => array('Heredoc' => 'Type/Heredoc', 'Nowdoc' => 'Type/Nowdoc'), 'Errors' => array('Throw exceptions' => 'Php/ThrowUsage', 'Try...Catch' => 'Php/TryCatchUsage', 'Multiple catch' => 'Structures/MultipleCatch', 'Multiple Exceptions' => 'Exceptions/MultipleCatch', 'Finally' => 'Structures/TryFinally', 'Trigger error' => 'Php/TriggerErrorUsage', 'Error messages' => 'Structures/ErrorMessages'), 'External systems' => array('System' => 'Structures/ShellUsage', 'Files' => 'Structures/FileUsage', 'LDAP' => 'Extensions/Extldap', 'mail' => 'Structures/MailUsage'), 'Extensions' => array('ext/amqp' => 'Extensions/Extamqp', 'ext/apache' => 'Extensions/Extapache', 'ext/apc' => 'Extensions/Extapc', 'ext/apcu' => 'Extensions/Extapcu', 'ext/array' => 'Extensions/Extarray', 'ext/ast' => 'Extensions/Extast', 'ext/bcmath' => 'Extensions/Extbcmath', 'ext/bzip2' => 'Extensions/Extbzip2', 'ext/cairo' => 'Extensions/Extcairo', 'ext/calendar' => 'Extensions/Extcalendar', 'ext/com' => 'Extensions/Extcom', 'ext/crypto' => 'Extensions/Extcrypto', 'ext/ctype' => 'Extensions/Extctype', 'ext/curl' => 'Extensions/Extcurl', 'ext/cyrus' => 'Extensions/Extcyrus', 'ext/date' => 'Extensions/Extdate', 'ext/dba' => 'Extensions/Extdba', 'ext/dio' => 'Extensions/Extdio', 'ext/dom' => 'Extensions/Extdom', 'ext/eaccelerator' => 'Extensions/Exteaccelerator', 'ext/enchant' => 'Extensions/Extenchant', 'ext/ereg' => 'Extensions/Extereg', 'ext/event' => 'Extensions/Extevent', 'ext/ev' => 'Extensions/Extev', 'ext/exif' => 'Extensions/Extexif', 'ext/expect' => 'Extensions/Extexpect', 'ext/fann' => 'Extensions/Extfann', 'ext/fdf' => 'Extensions/Extfdf', 'ext/ffmpeg' => 'Extensions/Extffmpeg', 'ext/file' => 'Extensions/Extfile', 'ext/fileinfo' => 'Extensions/Extfileinfo', 'ext/filter' => 'Extensions/Extfilter', 'ext/fpm' => 'Extensions/Extfpm', 'ext/ftp' => 'Extensions/Extftp', 'ext/gd' => 'Extensions/Extgd', 'ext/gearman' => 'Extensions/Extgearman', 'ext/geoip' => 'Extensions/Extgeoip', 'ext/gettext' => 'Extensions/Extgettext', 'ext/gmagick' => 'Extensions/Extgmagick', 'ext/gmp' => 'Extensions/Extgmp', 'ext/gnupg' => 'Extensions/Extgnupg', 'ext/hash' => 'Extensions/Exthash', 'ext/php_http' => 'Extensions/Exthttp', 'ext/ibase' => 'Extensions/Extibase', 'ext/iconv' => 'Extensions/Exticonv', 'ext/iis' => 'Extensions/Extiis', 'ext/imagick' => 'Extensions/Extimagick', 'ext/imap' => 'Extensions/Extimap', 'ext/info' => 'Extensions/Extinfo', 'ext/inotify' => 'Extensions/Extinotify', 'ext/intl' => 'Extensions/Extintl', 'ext/json' => 'Extensions/Extjson', 'ext/kdm5' => 'Extensions/Extkdm5', 'ext/ldap' => 'Extensions/Extldap', 'ext/libevent' => 'Extensions/Extlibevent', 'ext/libxml' => 'Extensions/Extlibxml', 'ext/mail' => 'Extensions/Extmail', 'ext/mailparse' => 'Extensions/Extmailparse', 'ext/math' => 'Extensions/Extmath', 'ext/mbstring' => 'Extensions/Extmbstring', 'ext/mcrypt' => 'Extensions/Extmcrypt', 'ext/memcache' => 'Extensions/Extmemcache', 'ext/memcached' => 'Extensions/Extmemcached', 'ext/ming' => 'Extensions/Extming', 'ext/mongo' => 'Extensions/Extmongo', 'ext/mssql' => 'Extensions/Extmssql', 'ext/mysql' => 'Extensions/Extmysql', 'ext/mysqli' => 'Extensions/Extmysqli', 'ext/ob' => 'Extensions/Extob', 'ext/oci8' => 'Extensions/Extoci8', 'ext/odbc' => 'Extensions/Extodbc', 'ext/opcache' => 'Extensions/Extopcache', 'ext/openssl' => 'Extensions/Extopenssl', 'ext/parsekit' => 'Extensions/Extparsekit', 'ext/pcntl' => 'Extensions/Extpcntl', 'ext/pcre' => 'Extensions/Extpcre', 'ext/pdo' => 'Extensions/Extpdo', 'ext/pgsql' => 'Extensions/Extpgsql', 'ext/phalcon' => 'Extensions/Extphalcon', 'ext/phar' => 'Extensions/Extphar', 'ext/posix' => 'Extensions/Extposix', 'ext/proctitle' => 'Extensions/Extproctitle', 'ext/pspell' => 'Extensions/Extpspell', 'ext/readline' => 'Extensions/Extreadline', 'ext/recode' => 'Extensions/Extrecode', 'ext/redis' => 'Extensions/Extredis', 'ext/reflexion' => 'Extensions/Extreflection', 'ext/runkit' => 'Extensions/Extrunkit', 'ext/sem' => 'Extensions/Extsem', 'ext/session' => 'Extensions/Extsession', 'ext/shmop' => 'Extensions/Extshmop', 'ext/simplexml' => 'Extensions/Extsimplexml', 'ext/snmp' => 'Extensions/Extsnmp', 'ext/soap' => 'Extensions/Extsoap', 'ext/sockets' => 'Extensions/Extsockets', 'ext/spl' => 'Extensions/Extspl', 'ext/sqlite' => 'Extensions/Extsqlite', 'ext/sqlite3' => 'Extensions/Extsqlite3', 'ext/sqlsrv' => 'Extensions/Extsqlsrv', 'ext/ssh2' => 'Extensions/Extssh2', 'ext/standard' => 'Extensions/Extstandard', 'ext/tidy' => 'Extensions/Exttidy', 'ext/tokenizer' => 'Extensions/Exttokenizer', 'ext/trader' => 'Extensions/Exttrader', 'ext/wddx' => 'Extensions/Extwddx', 'ext/wikidiff2' => 'Extensions/Extwikidiff2', 'ext/wincache' => 'Extensions/Extwincache', 'ext/xcache' => 'Extensions/Extxcache', 'ext/xdebug' => 'Extensions/Extxdebug', 'ext/xdiff' => 'Extensions/Extxdiff', 'ext/xhprof' => 'Extensions/Extxhprof', 'ext/xml' => 'Extensions/Extxml', 'ext/xmlreader' => 'Extensions/Extxmlreader', 'ext/xmlrpc' => 'Extensions/Extxmlrpc', 'ext/xmlwriter' => 'Extensions/Extxmlwriter', 'ext/xsl' => 'Extensions/Extxsl', 'ext/yaml' => 'Extensions/Extyaml', 'ext/yis' => 'Extensions/Extyis', 'ext/zip' => 'Extensions/Extzip', 'ext/zlib' => 'Extensions/Extzlib', 'ext/zmq' => 'Extensions/Extzmq')); // collecting information for Extensions $themed = Analyzer::getThemeAnalyzers('Appinfo'); $res = $this->sqlite->query('SELECT analyzer, count FROM resultsCounts WHERE analyzer IN ("' . implode('", "', $themed) . '")'); $sources = array(); while ($row = $res->fetchArray(\SQLITE3_ASSOC)) { $sources[$row['analyzer']] = $row['count']; } $data = array(); foreach ($extensions as $section => $hash) { $data[$section] = array(); foreach ($hash as $name => $ext) { if (!isset($sources[$ext])) { $data[$section][$name] = self::NOT_RUN; continue; } if (!in_array($ext, $themed)) { $data[$section][$name] = self::NOT_RUN; continue; } // incompatible if ($sources[$ext] == Analyzer::CONFIGURATION_INCOMPATIBLE) { $data[$section][$name] = self::INCOMPATIBLE; continue; } if ($sources[$ext] == Analyzer::VERSION_INCOMPATIBLE) { $data[$section][$name] = self::INCOMPATIBLE; continue; } $data[$section][$name] = $sources[$ext] > 0 ? self::YES : self::NO; } if ($section == 'Extensions') { $list = $data[$section]; uksort($data[$section], function ($ka, $kb) use($list) { if ($list[$ka] == $list[$kb]) { if ($ka > $kb) { return 1; } if ($ka == $kb) { return 0; } if ($ka > $kb) { return -1; } } else { return $list[$ka] == self::YES ? -1 : 1; } }); } } // collecting information for Composer if (isset($sources['Composer/PackagesNames'])) { $data['Composer Packages'] = array(); $res = $this->dump->query('SELECT fullcode FROM results WHERE analyzer = "Composer/PackagesNames"'); while ($row = $res->fetchArray(\SQLITE3_ASSOC)) { $data['Composer Packages'][] = $row['fullcode']; } } else { unset($data['Composer Packages']); } $list = array(); foreach ($data as $section => $points) { $listPoint = array(); foreach ($points as $point => $status) { $listPoint[] = '<li>' . $this->makeIcon($status) . ' ' . $point . '</li>'; } $listPoint = implode("\n", $listPoint); $list[] = <<<HTML <ul class="sidebar-menu"> <li class="treeview"> <a href="#"><i class="fa fa-certificate"></i> <span>{$section}</span><i class="fa fa-angle-left pull-right"></i></a> <ul class="treeview-menu"> {$listPoint} </ul> </li> </ul> HTML; } $list = implode("\n", $list); $list = <<<HTML <div class="sidebar"> {$list} </div> HTML; $html = $this->getBasedPage('appinfo'); $html = $this->injectBloc($html, 'APPINFO', $list); $this->putBasedPage('appinfo', $html); }
public function generate($folder, $name = null) { $themed = Analyzer::getThemeAnalyzers('Appinfo'); $res = $this->sqlite->query('SELECT analyzer, count FROM resultsCounts WHERE analyzer IN ("' . implode('", "', $themed) . '")'); $sources = array(); while ($row = $res->fetchArray(\SQLITE3_ASSOC)) { $sources[$row['analyzer']] = $row['count']; } $configureDirectives = json_decode(file_get_contents($this->config->dir_root . '/data/configure.json')); // preparing the list of PHP extensions to compile PHP with $return = array(<<<TEXT ;;;;;;;;;;;;;;;;;;;;;;;; ; PHP configure list ; ;;;;;;;;;;;;;;;;;;;;;;;; TEXT , './configure'); $pecl = array(); foreach ($configureDirectives as $ext => $configure) { if (isset($sources[$configure->analysis])) { if (!empty($configure->activate) && $sources[$configure->analysis] != 0) { $return[] = ' ' . $configure->activate; if (!empty($configure->others)) { $return[] = " " . join("\n ", $configure->others); } if (!empty($configure->pecl)) { $pecl[] = '#pecl install ' . basename($configure->pecl) . ' (' . $configure->pecl . ')'; } } elseif (!empty($configure->deactivate) && $sources[$configure->analysis] == 0) { $return[] = ' ' . $configure->deactivate; } } else { display("Missing {$configure->analysis} in sqlite\n"); } } $return = array_merge($return, array('', '; For debug purposes', ';--enable-dtrace', ';--disable-phpdbg', '', ';--enable-zend-signals', ';--disable-opcache')); $final = ''; if (!empty($pecl)) { $c = count($pecl); $final .= "# install " . ($c === 1 ? 'one' : $c) . " extra extension" . ($c === 1 ? '' : 's') . "\n"; $final .= implode("\n", $pecl) . "\n\n"; } $final .= implode("\n", $return); $shouldDisableFunctions = json_decode(file_get_contents($this->config->dir_root . '/data/shouldDisableFunction.json')); $functionsList = array(); $classesList = array(); foreach ((array) $shouldDisableFunctions as $ext => $toDisable) { if ($sources[$ext] == 0) { if (isset($toDisable->functions)) { $functionsList[] = $toDisable->functions; } if (isset($toDisable->classes)) { $classesList[] = $toDisable->classes; } } } if (empty($functionsList)) { $functionsList = ''; } else { $functionsList = call_user_func_array('array_merge', $functionsList); $functionsList = join(',', $functionsList); } if (empty($classesList)) { $classesList = ''; } else { $classesList = call_user_func_array('array_merge', $classesList); $classesList = join(',', $classesList); } // preparing the list of PHP directives to review before using this application $directives = array('standard', 'bcmath', 'date', 'file', 'fileupload', 'mail', 'ob', 'env', 'apc', 'amqp', 'apache', 'assertion', 'curl', 'dba', 'filter', 'image', 'intl', 'ldap', 'mbstring', 'opcache', 'openssl', 'pcre', 'pdo', 'pgsql', 'session', 'sqlite', 'sqlite3', 'com', 'eaccelerator', 'geoip', 'ibase', 'imagick', 'mailparse', 'mongo', 'trader', 'wincache', 'xcache'); $data = array(); $res = $this->sqlite->query(<<<SQL SELECT analyzer FROM resultsCounts WHERE ( analyzer LIKE "Extensions/Ext%" OR analyzer IN ("Structures/FileUploadUsage", "Php/UsesEnv")) AND count > 0 SQL ); while ($row = $res->fetchArray(\SQLITE3_ASSOC)) { if ($row['analyzer'] == 'Structures/FileUploadUsage') { $data['File Upload'] = (array) json_decode(file_get_contents($this->config->dir_root . '/data/directives/fileupload.json')); } elseif ($row['analyzer'] == 'Php/UsesEnv') { $data['Environnement'] = (array) json_decode(file_get_contents($this->config->dir_root . '/data/directives/env.json')); } else { $ext = substr($row['analyzer'], 14); if (in_array($ext, $directives)) { $data[$ext] = (array) json_decode(file_get_contents($this->config->dir_root . '/data/directives/' . $ext . '.json')); } } } $directives = <<<TEXT ;;;;;;;;;;;;;;;;;;;;;;;;;; ; Suggestion for php.ini ; ;;;;;;;;;;;;;;;;;;;;;;;;;; ; The directives below are selected based on the code provided. ; They only cover the related directives that may have an impact on the code ; ; The list may not be exhaustive ; The suggested values are not recommendations, and should be reviewed and adapted ; TEXT; foreach ($data as $section => $details) { $directives .= "[{$section}]\n"; foreach ((array) $details as $detail) { if ($detail->name == 'Extra configurations') { preg_match('#(http://[^"]+?)"#is', $detail->documentation, $url); $directives .= "; More information about {$section} : \n;{$url['1']}\n\n"; } else { $documentation = wordwrap(' ' . $detail->documentation, 80, "\n; "); $directives .= ";{$documentation}\n{$detail->name} = {$detail->suggested}\n\n"; } } if ($section === 'standard') { $directives .= ";{$documentation}\ndisable_functions = {$functionsList}\ndisable_classes = {$classesList}\n\n"; } $directives .= "\n\n"; } $final .= "\n\n" . $directives; if ($name === null) { return $final; } else { file_put_contents($folder . '/' . $name . '.' . self::FILE_EXTENSION, $final); return true; } }
protected function OneFile($title) { $css = new \Stdclass(); $css->displayTitles = true; $css->titles = array('Code', 'Analyzer', 'Line'); $css->sort = $css->titles; $return = $this->formatText('All results for the file : ' . $title, 'textLead'); $data = array(); $sqliteTitle = $this->dump->escapeString($title); $sqlQuery = <<<SQL SELECT fullcode as Code, analyzer AS Analyzer, line AS Line FROM results WHERE file="{$sqliteTitle}" AND analyzer IN {$this->themesList} SQL; $res = $this->dump->query($sqlQuery); while ($row = $res->fetchArray(SQLITE3_ASSOC)) { $analyzer = Analyzer::getInstance($row['Analyzer']); $row['File'] = $analyzer->getDescription()->getName(); $data[] = $row; } $return .= $this->formatHorizontal($data, $css); return $return; }
public function hasResults() { Analyzer::initDocs(); $report = Analyzer::$datastore->getHash('autoload') === 'psr-0' || Analyzer::$datastore->getHash('autoload') === 'psr-4'; return $report; }
public function run() { $project = $this->config->project; if ($project == 'default') { throw new ProjectNeeded($project); } if (!file_exists($this->config->projects_root . '/projects/' . $project)) { throw new NoSuchProject($project); } $this->checkTokenLimit(); $begin = microtime(true); Analyzer::$gremlinStatic = $this->gremlin; // Take this before we clean it up $rows = $this->datastore->getRow('analyzed'); $analyzed = array(); foreach ($rows as $row) { $analyzed[$row['analyzer']] = $row['counts']; } if ($this->config->program !== null) { $analyzer = $this->config->program; if (Analyzer::getClass($analyzer)) { $analyzers_class = array($analyzer); } else { $r = Analyzer::getSuggestionClass($analyzer); if (count($r) > 0) { echo 'did you mean : ', implode(', ', str_replace('_', '/', $r)), "\n"; } throw new NoSuchAnalyzer($analyzer); } } elseif (is_string($this->config->thema)) { $thema = $this->config->thema; if (!($analyzers_class = Analyzer::getThemeAnalyzers($thema))) { throw new NoSuchAnalyzer($thema); } $this->datastore->addRow('hash', array($this->config->thema => count($analyzers_class))); } else { die("Usage :php exakat analyze -T <\"Thema\"> -p <project>\n\nphp exakat analyze -P <One/rule> -p <project>\n"); } $this->log->log("Analyzing project {$project}"); $this->log->log("Runnable analyzers\t" . count($analyzers_class)); if ($this->config->noDependencies) { $dependencies2 = $analyzers_class; } else { $dependencies = array(); $dependencies2 = array(); foreach ($analyzers_class as $a) { $d = Analyzer::getInstance($a); $this->configName = str_replace('/', '_', $a); $d = $d->dependsOn(); if (!is_array($d)) { throw new DependsOnMustReturnArray(get_class($this)); } if (empty($d)) { $dependencies2[] = $a; } else { $diff = array_diff($d, $dependencies2); if (empty($diff)) { $dependencies2[] = $a; } else { $dependencies[$a] = $diff; } } } $c = count($dependencies) + 1; while (!empty($dependencies) && $c > count($dependencies)) { $c = count($dependencies); foreach ($dependencies as $a => &$d) { $diff = array_diff($d, $dependencies2); foreach ($diff as $k => $v) { if (!isset($dependencies[$v])) { $x = Analyzer::getInstance($v); if ($x === null) { display("No such dependency as '{$v}'. Ignoring\n"); continue; } $dep = $x->dependsOn(); if (count($dep) == 0) { $dependencies2[] = $v; ++$c; } else { $dependencies[$v] = $dep; $c += count($dep) + 1; } } elseif (count($dependencies[$v]) == 0) { $dependencies2[] = $v; unset($diff[$k]); } } if (empty($diff)) { $dependencies2[] = $a; unset($dependencies[$a]); } else { $d = $diff; } } unset($d); } if (!empty($dependencies)) { die("Dependencies depending on each other : can't finalize. Aborting\n" . print_r($dependencies, true)); } } $total_results = 0; $Php = new Phpexec($this->config->version); $progressBar = new Progressbar(0, count($dependencies2) + 1, exec('tput cols')); foreach ($dependencies2 as $analyzer_class) { if (!$this->config->verbose && !$this->config->quiet) { echo $progressBar->advance(); } $begin = microtime(true); $analyzer = Analyzer::getInstance($analyzer_class); $this->configName = str_replace(array('/', '\\', 'Exakat\\Analyzer\\'), array('_', '_', ''), $analyzer_class); if ($this->config->noRefresh === true && isset($analyzed[$analyzer_class])) { display("{$analyzer_class} is already processed\n"); continue 1; } $analyzer->init(); if (!$analyzer->checkPhpVersion($this->config->phpversion)) { $analyzerQuoted = str_replace('\\', '\\\\', get_class($analyzer)); $analyzer = str_replace('\\', '\\\\', $analyzer_class); $query = <<<GREMLIN result = g.addV('Noresult').property('code', 'Not Compatible With PhpVersion') .property('fullcode', 'Not Compatible With PhpVersion') .property('virtual', true) .property('notCompatibleWithPhpVersion', '{$this->config->phpversion}') .property('token', 'T_INCOMPATIBLE'); g.addV('Analysis').property('analyzer', '{$analyzerQuoted}').addE('ANALYZED').to(result); GREMLIN; $this->gremlin->query($query); $this->datastore->addRow('analyzed', array($analyzer_class => -2)); display("{$analyzer} is not compatible with PHP version {$this->config->phpversion}. Ignoring\n"); } elseif (!$analyzer->checkPhpConfiguration($Php)) { $analyzerQuoted = str_replace('\\', '\\\\', get_class($analyzer)); $analyzer = str_replace('\\', '\\\\', $analyzer_class); $query = <<<GREMLIN result = g.addV('Noresult').property('code', 'Not Compatible With Configuration') .property('fullcode', 'Not Compatible With Configuration') .property('virtual', true) .property('notCompatibleWithPhpConfiguration', '{$this->config->phpversion}') .property('token', 'T_INCOMPATIBLE'); index = g.addV('Analysis').property('analyzer', '{$analyzerQuoted}').addE('ANALYZED').to(result); GREMLIN; $this->gremlin->query($query); $this->datastore->addRow('analyzed', array($analyzer_class => -1)); display("{$analyzer} is not compatible with PHP configuration of this version. Ignoring\n"); } else { display("{$analyzer_class} running\n"); $analyzer->run(); $count = $analyzer->getRowCount(); $processed = $analyzer->getProcessedCount(); $queries = $analyzer->getQueryCount(); $rawQueries = $analyzer->getRawQueryCount(); $total_results += $count; display("{$analyzer_class} run ({$count} / {$processed})\n"); $end = microtime(true); $this->log->log("{$analyzer_class}\t" . ($end - $begin) . "\t{$count}\t{$processed}\t{$queries}\t{$rawQueries}"); // storing the number of row found in Hash table (datastore) $this->datastore->addRow('analyzed', array($analyzer_class => $count)); } } if (!$this->config->verbose && !$this->config->quiet) { echo $progressBar->advance(); } display("Done\n"); }
public function hasResults() { Analyzer::initDocs(); $report = Analyzer::$datastore->getHash('composer.json') === '1'; return $report; }
public function generate($folder, $name = 'report') { $finalName = $name; $name = '.' . $name; if ($name === null) { return "Can't produce Devoops format to stdout"; } // Clean final destination if ($folder . '/' . $finalName !== '/') { rmdirRecursive($folder . '/' . $finalName); } if (file_exists($folder . '/' . $finalName)) { display($folder . '/' . $finalName . " folder was not cleaned. Please, remove it before producing the report. Aborting report\n"); return; } // Clean temporary destination if (file_exists($folder . '/' . $name)) { rmdirRecursive($folder . '/' . $name); } mkdir($folder . '/' . $name, Devoops::FOLDER_PRIVILEGES); mkdir($folder . '/' . $name . '/ajax', Devoops::FOLDER_PRIVILEGES); copyDir($this->config->dir_root . '/media/devoops/css', $folder . '/' . $name . '/css'); copyDir($this->config->dir_root . '/media/devoops/img', $folder . '/' . $name . '/img'); copyDir($this->config->dir_root . '/media/devoops/js', $folder . '/' . $name . '/js'); copyDir($this->config->dir_root . '/media/devoops/plugins', $folder . '/' . $name . '/plugins'); display("Copied media files"); $this->dump = new \Sqlite3($folder . '/dump.sqlite', SQLITE3_OPEN_READONLY); $this->datastore = new \sqlite3($folder . '/datastore.sqlite', \SQLITE3_OPEN_READONLY); // Compatibility $compatibility = array('Compilation' => 'Compilation'); foreach ($this->config->other_php_versions as $code) { if ($code == 52) { continue; } $version = $code[0] . '.' . substr($code, 1); $compatibility['Compatibility ' . $version] = 'Compatibility'; } // Analyze $analyze = array(); //count > 0 AND print 'SELECT * FROM resultsCounts WHERE analyzer in ' . $this->themesList . ' ORDER BY id'; $res = $this->sqlite->query('SELECT * FROM resultsCounts WHERE analyzer in ' . $this->themesList); while ($row = $res->fetchArray()) { $analyzer = Analyzer::getInstance($row['analyzer']); $this->analyzers[$analyzer->getDescription()->getName()] = $analyzer; $analyze[$analyzer->getDescription()->getName()] = 'OneAnalyzer'; } uksort($analyze, function ($a, $b) { return -strnatcmp($a, $b); }); $analyze = array_merge(array('Results Counts' => 'AnalyzersResultsCounts'), $analyze); // Files $files = array(); $res = $this->sqlite->query('SELECT DISTINCT file FROM results ORDER BY file'); while ($row = $res->fetchArray()) { $files[$row['file']] = 'OneFile'; } $files = array_merge(array('Files Counts' => 'FilesResultsCounts'), $files); $summary = array('Report presentation' => array('Audit configuration' => 'AuditConfiguration', 'Processed Files' => 'ProcessedFiles', 'Non-processed Files' => 'NonProcessedFiles'), 'Zend Framework' => $analyze); $summaryHtml = $this->makeSummary($summary); $faviconHtml = ''; if (file_exists($this->config->dir_root . '/projects/' . $this->config->project . '/code/favicon.ico')) { // Should be checked and reported copy($this->config->dir_root . '/projects/' . $this->config->project . '/code/favicon.ico', $folder . '/' . $name . '/img/' . $this->config->project . '.ico'); $faviconHtml = <<<HTML <img src="img/{$this->config->project}.ico" class="img-circle" alt="{$this->config->project} logo" /> HTML; if (!empty($this->config->project_url)) { $faviconHtml = "<a href=\"{$this->config->project_url}\" class=\"avatar\">{$faviconHtml}</a>"; } $faviconHtml = <<<HTML \t\t\t\t<div class="avatar"> \t\t\t\t\t{$faviconHtml} \t\t\t\t</div> HTML; } $html = file_get_contents($this->config->dir_root . '/media/devoops/index.exakat.html'); $html = str_replace('<menu>', $summaryHtml, $html); $html = str_replace('EXAKAT_VERSION', Exakat::VERSION, $html); $html = str_replace('EXAKAT_BUILD', Exakat::BUILD, $html); $html = str_replace('PROJECT_NAME', $this->config->project_name, $html); $html = str_replace('PROJECT_FAVICON', $faviconHtml, $html); file_put_contents($folder . '/' . $name . '/index.html', $html); foreach ($summary as $titleUp => $section) { foreach ($section as $title => $method) { if (method_exists($this, $method)) { $html = $this->{$method}($title); } else { $html = 'Using default for ' . $title . "\n"; display($html); } $filename = $this->makeFileName($title); $html = <<<HTML <script language="javascript"> if (!document.getElementById("main")) { window.location.href = "../index.html#ajax/{$filename}"; } </script > <div class="row"> \t<div id="breadcrumb" class="col-xs-12"> \t\t<a href="#" class="show-sidebar"> \t\t\t<i class="fa fa-bars"></i> \t\t</a> \t\t<ol class="breadcrumb pull-left"> \t\t\t<li><a href="index.html">Dashboard</a></li> \t\t\t<li><a href="#ajax/About-This-Report.html">About This Report</a></li> \t\t</ol> \t</div> </div> <h4 class="page-header">{$title}</h4> <div class="row"> \t<div class="col-xs-12"> {$html} </div> </div> HTML; file_put_contents($folder . '/' . $name . '/ajax/' . $filename, $html); } } rename($folder . '/' . $name, $folder . '/' . $finalName); return ''; }
public function generic_test($file) { list($analyzer, $number) = explode('.', $file); $analyzer = str_replace('_', '/', $analyzer); // Test are run with test project. $ini = parse_ini_file('../../projects/test/config.ini'); $phpversion = empty($ini['phpversion']) ? phpversion() : $ini['phpversion']; $test_config = str_replace('_', '/', substr(get_class($this), 5)); // initialize Config (needed by phpexec) $config = \Exakat\Config::factory(array('foo', '-p', 'test')); $analyzerobject = ExakatAnalyzer::getInstance($test_config); if (!$analyzerobject->checkPhpVersion($phpversion)) { $this->markTestSkipped('Needs version ' . $analyzerobject->getPhpVersion() . '.'); } require 'exp/' . str_replace('_', '/', $file) . '.php'; $versionPHP = 'php' . str_replace('.', '', $phpversion); $res = shell_exec($config->{$versionPHP} . ' -l ./source/' . str_replace('_', '/', $file) . '.php 2>/dev/null'); if (strpos($res, 'No syntax errors detected') === false) { $this->markTestSkipped('Compilation problem : "' . $res . '".'); } $Php = new Phpexec($phpversion); if (!$analyzerobject->checkPhpConfiguration($Php)) { $message = array(); $confs = $analyzerobject->getPhpConfiguration(); if (is_array($confs)) { foreach ($confs as $name => $value) { $confs[] = "{$name} => {$value}"; } $confs = join(', ', $confs); } $this->markTestSkipped('Needs configuration : ' . $confs . '.'); } $analyzer = escapeshellarg($test_config); $source = 'source/' . str_replace('_', '/', $file) . '.php'; if (is_dir($source)) { $shell = 'cd ../..; php exakat test -r -d ./tests/analyzer/' . $source . ' -P ' . $analyzer . ' -p test -q -o -json'; } else { $shell = 'cd ../..; php exakat test -f ./tests/analyzer/' . $source . ' -P ' . $analyzer . ' -p test -q -o -json'; } $shell_res = shell_exec($shell); $res = json_decode($shell_res); if ($res === null) { $this->assertTrue(false, "Json couldn't be decoded : '{$shell_res}'\n{$shell}"); } if (empty($res)) { $list = array(); } else { $list = array(); foreach ($res as $r) { $list[] = $r[0]; } $this->assertNotEquals(count($list), 0, 'No values were read from the analyzer'); } if (isset($expected) && is_array($expected)) { $missing = array(); foreach ($expected as $e) { if (($id = array_search($e, $list)) !== false) { unset($list[$id]); } else { $missing[] = $e; } } $list = array_map(function ($x) { return str_replace("'", "\\'", $x); }, $list); $this->assertEquals(count($missing), 0, count($missing) . " expected values were not found :\n '" . join("',\n '", $missing) . "'\n\nin the " . count($list) . " received values of \n '" . join("', \n '", $list) . "'\n\nsource/{$file}.php\nexp/{$file}.php\nphpunit --filter={$number} Test/{$analyzer}.php\n\n"); // also add a phpunit --filter to rerun it easily } if (isset($expected_not) && is_array($expected)) { $extra = array(); foreach ($expected_not as $e) { if ($id = array_search($e, $list)) { $extra[] = $e; unset($list[$id]); } } // the not expected $this->assertEquals(count($extra), 0, count($extra) . " values were found and shouldn't be : " . join(', ', $extra) . ""); } // the remainings $this->assertEquals(count($list), 0, count($list) . " values were found and are unprocessed : " . join(', ', $list) . ""); }
private function processResults($class, $count) { $this->cleanResults->bindValue(':analyzer', $class, \SQLITE3_TEXT); $this->cleanResults->execute(); $this->stmtResultsCounts->bindValue(':class', $class, \SQLITE3_TEXT); $this->stmtResultsCounts->bindValue(':count', $count, \SQLITE3_INTEGER); $result = $this->stmtResultsCounts->execute(); $this->log->log("{$class} : {$count}\n"); // No need to go further if ($count <= 0) { return; } $this->stmtResults->bindValue(':class', $class, \SQLITE3_TEXT); $analyzer = Analyzer::getInstance($class); $res = $analyzer->getDump(); $saved = 0; $severity = $analyzer->getSeverity(); foreach ($res as $id => $result) { if (!is_object($result)) { $this->log->log("Object expected but not found\n" . print_r($result, true) . "\n"); continue; } if (!isset($result->class)) { continue; } $this->stmtResults->bindValue(':fullcode', $result->fullcode, \SQLITE3_TEXT); $this->stmtResults->bindValue(':file', $result->file, \SQLITE3_TEXT); $this->stmtResults->bindValue(':line', $result->line, \SQLITE3_INTEGER); $this->stmtResults->bindValue(':namespace', $result->{'namespace'}, \SQLITE3_TEXT); $this->stmtResults->bindValue(':class', $result->class, \SQLITE3_TEXT); $this->stmtResults->bindValue(':function', $result->function, \SQLITE3_TEXT); $this->stmtResults->bindValue(':analyzer', $class, \SQLITE3_TEXT); $this->stmtResults->bindValue(':severity', $severity, \SQLITE3_TEXT); $this->stmtResults->execute(); ++$saved; } $this->log->log("{$class} : dumped {$saved}"); if ($count != $saved) { display("{$saved} results saved, {$count} expected for {$class}\n"); } else { display("All {$saved} results saved for {$class}\n"); } }