public static function create($path, $name) { $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $prettyPrinter = new CodePrinter(); $path = explode(".", $path); $controllerPath = ""; if (count($path) == 1) { $controllerPath = $path[0] . ".controllers." . $name; } else { if (count($path) == 2) { $controllerPath = $path[0] . ".modules." . $path[1] . ".controllers." . $name; } } try { $templatePath = Yii::getPathOfAlias("application.components.codegen.templates.controller") . ".php"; $template = file_get_contents($templatePath); $stmts = $parser->parse($template); $stmts[0]->name = ucfirst($name); $generated = $prettyPrinter->prettyPrintFile($stmts); $cp = Yii::getPathOfAlias($controllerPath) . ".php"; if (!is_dir(dirname($cp))) { mkdir(dirname($cp), 0777, true); } file_put_contents($cp, $generated); return true; } catch (Exception $e) { return false; } }
public function obfuscate() { $content = $this->source; $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $prettyPrinter = new PhpParser\PrettyPrinter\Obfuscated(); // add your visitors $traverser->addVisitor(new StringNodeVisitor()); $traverser->addVisitor(new VariableNodeVisitor()); $traverser->addVisitor(new DigitNodeVisitor()); $f = new FunctionNodeVisitor(); $traverser->addVisitor($f); try { $stmts = $parser->parse($content); $stmts = $traverser->traverse($stmts); $nodeWithFunctionNames = $f->getNativeFunctionNamesNode(); $userDefinedFunctionNames = $f->getUserDefinedFunctionNames(); $f2 = new Function2NodeVisitor($nodeWithFunctionNames, $userDefinedFunctionNames); $traverser2 = new PhpParser\NodeTraverser(); $traverser2->addVisitor($f2); $stmts = array_merge(array($nodeWithFunctionNames['']), $stmts); $stmts = $traverser2->traverse($stmts); $content = $prettyPrinter->prettyPrintFile($stmts); return $content; } catch (PhpParser\Error $e) { return 'Parse Error: ' . $e->getMessage(); } }
/** * 得到一个文件基本信息FileSummary,包括路径,基本块,包含的文件等 * @param string $absPath */ public static function getFileSummary($absPath) { if (!$absPath) { return; } $visitor = new MyVisitor(); $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $code = file_get_contents($absPath); try { $stmts = $parser->parse($code); } catch (Exception $e) { return; } $traverser->addVisitor($visitor); $traverser->traverse($stmts); $nodes = $visitor->getNodes(); $fileSummary = new FileSummary(); $fileSummary->setPath($absPath); $currBlock = new BasicBlock(); foreach ($nodes as $node) { if (!is_object($node)) { continue; } //不分析函数定义 if ($node->getType() == "Stmt_Function") { continue; } $currBlock->addNode($node); } $fileSummaryGenerator = new FileSummaryGenerator(); $fileSummaryGenerator->simulate($currBlock, $fileSummary); return $fileSummary; }
/** * 通过判断文件中Nodes的数量和class node和 function node数量比较,找出main php files * @param php项目文件夹路径$dirpath * @return multitype: */ public static function mainFileFinder($dirpath) { $files = self::getPHPfile($dirpath); $should2parser = array(); $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $visitor = new VisitorForLine(); $traverser->addVisitor($visitor); foreach ($files as $file) { $code = file_get_contents($file); try { $stmts = $parser->parse($code); } catch (PhpParser\Error $e) { continue; } $traverser->traverse($stmts); $nodes = $visitor->getNodes(); $sumcount = count($nodes); $count = $visitor->getCount(); if ($sumcount == 0) { continue; } //暂时确定当比值小于0.6,为main php files if ($count / $sumcount < 0.6) { array_push($should2parser, $file); } $visitor->setCount(0); $visitor->setNodes(array()); } return $should2parser; }
/** @test */ public function it_should_hoge() { $path = dirname(__DIR__) . DIRECTORY_SEPARATOR . "fixtures" . DIRECTORY_SEPARATOR . "simple.bin"; $data = file_get_contents($path); $compiler = new \protocolbuffers\Compiler(); $response = $compiler->compile($data); /** @var \google\protobuf\compiler\CodeGeneratorResponse $response */ $file = $response->getFile(2); $this->assertTrue((bool) preg_match("/Person\\.php/", $file->getName())); $file->getContent(); $parser = new PhpParser\Parser(new PhpParser\Lexer()); $stmts = $parser->parse((string) $file->getContent()); $class = $stmts[0]; /** @var PhpParser\Node\Stmt\Class_ $class */ $this->assertInstanceof('PhpParser\\Node\\Stmt\\Class_', $class); $this->assertEquals("Person", $class->name); $properties = array(); foreach ($class->stmts as $stmt) { if ($stmt instanceof PhpParser\Node\Stmt\Property) { $properties[] = $stmt; } } foreach ($properties as $prop) { /** @var PhpParser\Node\Stmt\Property $prop */ $this->assertEquals("name", $prop->props[0]->name); $this->assertTrue($prop->isProtected()); } }
/** * @param $phpCodeString * @throws \Exception */ public function transpile($phpCode) { $parser = new \PhpParser\Parser(new \PhpParser\Lexer()); $ast = $parser->parse($phpCode); $transpiler = new FileTranspiler($ast); $transpiler->setConfiguration($this->configuration); $result = $transpiler->transpile(); return $result; }
public function findChangedSymbols() { $parser = new \PhpParser\Parser(new \PhpParser\Lexer()); $oldStmts = $parser->parse($this->oldSrc); $newStmts = $parser->parse($this->newSrc); $oldSymbols = $this->createSymbolTable($oldStmts); $newSymbols = $this->createSymbolTable($newStmts); $commonSymbols = array_intersect(array_keys($oldSymbols), array_keys($newSymbols)); // Wholesale additions and removals. $changedSymbols = array_diff(array_keys($oldSymbols), $commonSymbols) + array_diff(array_keys($newSymbols), $commonSymbols); // Incremental/internal changes foreach ($commonSymbols as $commonSymbol) { if (!$this->isEqual($oldSymbols[$commonSymbol], $newSymbols[$commonSymbol])) { $changedSymbols[] = $commonSymbol; } } sort($changedSymbols); return $changedSymbols; }
public function execute() { $parser = new \PhpParser\Parser(new \PhpParser\Lexer()); try { $stmts = $parser->parse(file_get_contents("/home/www/workspace/ftwo/src/Flexy/Ftwo/Store/Bundle/StoreBundle/Controller/ProductController.php")); print_r($stmts); } catch (\PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } }
/** * @param $cache_file * @param array $source_files */ public function generateMerge($cache_file, array $source_files) { $parser = new \PhpParser\Parser(new \PhpParser\Lexer()); $config = new \PhpParser\Node\Expr\Array_(); foreach ($source_files as $basename => $file) { $stmts = $parser->parse(file_get_contents($file)); if (empty($stmts) || !$stmts[0] instanceof \PhpParser\Node\Stmt\Return_) { throw new \RuntimeException("Unable to locate return statement with config items in {$file}"); } $config->items[] = new \PhpParser\Node\Expr\ArrayItem($stmts[0]->expr, new \PhpParser\Node\Scalar\String_($basename)); } $prettyPrinter = new \PhpParser\PrettyPrinter\Standard(); $out = $prettyPrinter->prettyPrintExpr($config); file_put_contents($cache_file, '<?php' . PHP_EOL . PHP_EOL . '// THIS IS AUTOGENERATED FILE! DO NOT EDIT IT!' . PHP_EOL . PHP_EOL . 'return ' . $out . ';' . PHP_EOL); }
/** * 处理单个文件的静态检测 * 输入PHP文件 * @param string $path */ function load_file($path) { $cfg = new CFGGenerator(); $cfg->getFileSummary()->setPath($path); $visitor = new MyVisitor(); $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $code = file_get_contents($path); $stmts = $parser->parse($code); $traverser->addVisitor($visitor); $traverser->traverse($stmts); $nodes = $visitor->getNodes(); $pEntryBlock = new BasicBlock(); $pEntryBlock->is_entry = true; //开始分析 $cfg->CFGBuilder($nodes, NULL, NULL, NULL); }
public static function patch($source) { $patched = false; self::$replacement = []; $parser = new PhpParser\Parser(new PhpParser\Lexer(['usedAttributes' => ['startTokenPos', 'endTokenPos']])); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor(new CIPHPUnitTestFunctionPatcherNodeVisitor()); $ast_orig = $parser->parse($source); $traverser->traverse($ast_orig); if (self::$replacement !== []) { $patched = true; $new_source = self::generateNewSource($source); } else { $new_source = $source; } return [$new_source, $patched]; }
/** * Analyzes this file. * * @throws PhpParser\Error if the file cannot be parsed. */ protected function analyze_file() { // Load the contents of the file if (is_null($this->filecontents) || !$this->filecontents) { $this->filecontents = file_get_contents($this->filepath); } if (false === $this->filecontents) { return; } // Parse the tokens $parser = new PhpParser\Parser(new PhpParser\Lexer()); $this->node_tree = $parser->parse($this->filecontents); // Pre-process the parsed elements for further usage $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor(new ScopeVisitor()); $traverser->addVisitor(new InAssignmentVisitor()); $this->node_tree = $traverser->traverse($this->node_tree); }
public static function parseClass($path) { $code = file_get_contents($path); $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); try { $stmts = $parser->parse($code); $class = new CodeGenerator\ClassGenerator(); $class->name = $stmts[0]->name; $class->extends = implode(',', $stmts[0]->extends->parts); foreach ($stmts[0]->stmts as $stmt) { if (get_class($stmt) == 'PhpParser\\Node\\Stmt\\ClassMethod') { $class->addMethod($stmt->name); } } return $class; // $stmts is an array of statement nodes } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); exit; } }
public function filter() { $sourceFileContent = trim(file_get_contents($this->sourceFile)); //first, remove all comments in file content $sourceFileContent = $this->removeAllComments($sourceFileContent); $sourceFileContent = $this->putBracketsInNewLine($sourceFileContent); $sourceFileContent = $this->removeBlankLines($sourceFileContent); $parser = new \PhpParser\Parser(new \PhpParser\Lexer()); $serializer = new \PhpParser\Serializer\XML(); try { //load all converters, order is very important $converterClasses = array("\\PHPtoCExt\\Converter\\TraitMergingConverter", "\\PHPtoCExt\\Converter\\ForLoopToWhileLoopConverter", "\\PHPtoCExt\\Converter\\PrintToEchoConverter", "\\PHPtoCExt\\Converter\\ModuloCastingConverter", "\\PHPtoCExt\\Converter\\IssetToNotEmptyConverter", "\\PHPtoCExt\\Converter\\ClassHierarchyFlatterningConverter", "\\PHPtoCExt\\Converter\\StaticVarAutoDefineConverter", "\\PHPtoCExt\\Converter\\SelfStaticConverter", "\\PHPtoCExt\\Converter\\CodeReformatConverter", "\\PHPtoCExt\\Converter\\CFunctionAutoConverter", "\\PHPtoCExt\\Converter\\CFunctionCallConverter"); $searches = array(); $replaces = array(); $postSearches = array(); $postReplaces = array(); //go through all converters to convert the source code foreach ($converterClasses as $converterClass) { $stmts = $parser->parse($sourceFileContent); $codeLines = explode("\n", $sourceFileContent); $codeASTXML = $serializer->serialize($stmts); $codeASTXMLLines = explode("\n", $codeASTXML); $this->codeLines = $codeLines; $this->codeASTXMLLines = $codeASTXMLLines; $this->converter = new $converterClass($codeLines, $codeASTXMLLines, $this->inputDir); $this->converter->convert(); $searches = $this->converter->getSearches(); $replaces = $this->converter->getReplaces(); $sourceFileContent = str_replace($searches, $replaces, $sourceFileContent); $postSearches = array_merge($postSearches, $this->converter->getPostSearches()); $postReplaces = array_merge($postReplaces, $this->converter->getPostReplaces()); } file_put_contents($this->targetFile, $sourceFileContent); //add post searches and replaces $this->postSearches = $postSearches; $this->postReplaces = $postReplaces; } catch (\PhpParser\Error $e) { throw new PHPtoCExtException("PHP Parser Error: " . $e->getMessage()); } }
public function setCache() { //empty the cache folder $this->cleanFolder(); $phpbb_root_path = get_option('wpphpbbu_path', false); $phpEx = 'php'; $GLOBALS['phpbb_root_path'] = get_option('wpphpbbu_path', false); $GLOBALS['phpEx'] = 'php'; $GLOBALS['phpbb_root_path'] = $phpbb_root_path; //fix make_clickable $parser = new \PhpParser\Parser(new \PhpParser\Lexer()); $prettyPrinter = new \PhpParser\PrettyPrinter\Standard(); try { $searched_function[] = "make_clickable"; $traverser_safety = new \PhpParser\NodeTraverser(); $traverser_safety->addVisitor(new \SafeFunction($searched_function)); // parse $raw = file_get_contents($phpbb_root_path . 'includes/functions_content.' . $phpEx); $stmts = $parser->parse($raw); // traverse $stmts = $traverser_safety->traverse($stmts); // pretty print $code = $prettyPrinter->prettyPrint($stmts); file_put_contents(__DIR__ . '/cache/functions_content.' . $phpEx, '<?php ' . $code . ' ?>'); } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } try { $searched_function[] = "validate_username"; $traverser_safety = new \PhpParser\NodeTraverser(); $traverser_safety->addVisitor(new \SafeFunction($searched_function)); // parse $raw = file_get_contents($phpbb_root_path . 'includes/functions_user.' . $phpEx); $stmts = $parser->parse($raw); // traverse $stmts = $traverser_safety->traverse($stmts); // pretty print $code = $prettyPrinter->prettyPrint($stmts); file_put_contents(__DIR__ . '/cache/functions_user.' . $phpEx, '<?php ' . $code . ' ?>'); } catch (\PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } //unicorn code is actually useless, im bored. At least, it was a good exercise try { $traverser_path = new \PhpParser\NodeTraverser(); //dont forget to escape the path, = preq_quote? $mypath = __DIR__; $traverser_path->addVisitor(new \PathFixer("\$phpbb_root_path \\. \\'includes/functions_content.\\' \\. \$phpEx", [new \PhpParser\Node\Scalar\String_($mypath . '/cache/functions_content.'), new \PhpParser\Node\Expr\Variable('phpEx')])); //fix path to functions_content $raw = file_get_contents($phpbb_root_path . 'common.' . $phpEx); // parse $stmts = $parser->parse($raw); // traverse $stmts = $traverser_path->traverse($stmts); // pretty print $code = $prettyPrinter->prettyPrint($stmts); file_put_contents(__DIR__ . '/cache/common.' . $phpEx, '<?php ' . $code . ' ?>'); } catch (\PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } }
/** * @param 包含函数的文件路径 $path * @param 函数的信息 $mehod * @return 函数体 */ public function getFunction($path, $method) { //设置code if (!$path) { return null; } $code = file_get_contents($path); //找到了相应的方法名称 if ($method && $code) { $startLine = $method['startLine']; $endLine = $method['endLine']; $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $visitor = new FunctionBodyVisitor(); $traverser = new PhpParser\NodeTraverser(); $visitor->startLine = $startLine; $visitor->endLine = $endLine; $visitor->funcName = $method['name']; try { $stmts = $parser->parse($code); } catch (Exception $e) { return null; } $traverser->addVisitor($visitor); $traverser->traverse($stmts); return $visitor->getFunctionBody(); } else { return NULL; } }
/** * @ignore */ public static function onThirdPartyUpdateByPackageManager() { if (!self::isInCliMode()) { // This method can be run in CLI mode only. assert('false', vs(isset($this), get_defined_vars())); } $timeoutPause = new CTimeoutPause(); CShell::speak("Processing third-party components ..."); $tpDps = CFile::listDirectories(CFilePath::absolute($GLOBALS["PHRED_PATH_TO_THIRD_PARTY"])); $ignorePackages = CConfiguration::option("upd.thirdPartyOopWrappingIgnorePackages"); $ignorePackagesL2 = CArray::filter($ignorePackages, function ($package) { return CString::find($package, "/"); }); $newTpDps = CArray::make(); $len = CArray::length($tpDps); for ($i = 0; $i < $len; $i++) { $tpDp = $tpDps[$i]; $dirName = CFilePath::name($tpDp); if (!CArray::find($ignorePackages, $dirName)) { $dpHasL2DirsToIgnore = CArray::find($ignorePackagesL2, $dirName, function ($packageL2, $dirName) { return CString::equals(CFilePath::directory($packageL2), $dirName); }); if (!$dpHasL2DirsToIgnore) { CArray::push($newTpDps, $tpDp); } else { $tpSubDps = CFile::listDirectories($tpDp); $tpSubDps = CArray::filter($tpSubDps, function ($subDp) use($ignorePackagesL2) { return !CArray::find($ignorePackagesL2, $subDp, function ($packageL2, $subDp) { return CString::endsWith($subDp, $packageL2); }); }); CArray::pushArray($newTpDps, $tpSubDps); } } } $tpDps = $newTpDps; $wrapProtectedMethods = CConfiguration::option("upd.thirdPartyOopWrappingInProtectedMethods"); $wrapPrivateMethods = CConfiguration::option("upd.thirdPartyOopWrappingInPrivateMethods"); static $s_stdPhpTag = "<?php"; static $s_progressResolution = 0.05; $prevProgressDivR = 0; $tpDpsLen = CArray::length($tpDps); for ($i0 = 0; $i0 < $tpDpsLen; $i0++) { $tpFps = CFile::reFindFilesRecursive($tpDps[$i0], "/\\.php\\d?\\z/"); $tpFpsLen = CArray::length($tpFps); for ($i1 = 0; $i1 < $tpFpsLen; $i1++) { $fileCode = CFile::read($tpFps[$i1]); if (!CString::find($fileCode, self::$ms_thirdPartyAlreadyOopWrappedMark)) { $parser = new PhpParser\Parser(new PhpParser\Lexer()); try { // Parse the code. $statements = $parser->parse($fileCode); // Wrap the code into OOP. $traverser = new PhpParser\NodeTraverser(); $mainVisitor = new CMainVisitor($wrapProtectedMethods, $wrapPrivateMethods); $traverser->addVisitor($mainVisitor); $statements = $traverser->traverse($statements); $wrappedCode = (new PhpParser\PrettyPrinter\Standard())->prettyPrint($statements); $phpTagPos = CString::indexOf($wrappedCode, $s_stdPhpTag); if ($phpTagPos == -1) { $wrappedCode = "{$s_stdPhpTag}\n\n{$wrappedCode}"; $phpTagPos = 0; } $wrappedCode = CString::insert($wrappedCode, $phpTagPos + CString::length($s_stdPhpTag), "\n\n" . self::$ms_thirdPartyAlreadyOopWrappedMark); // Save. CFile::write($tpFps[$i1], $wrappedCode); } catch (PhpParser\Error $parserError) { CShell::say("\nPhpParser: " . $tpFps[$i1] . ", at line " . $parserError->getRawLine() . ": " . $parserError->getRawMessage()); } } $progress = (double) ($i0 / $tpDpsLen + 1 / $tpDpsLen * $i1 / $tpFpsLen); $progressDivR = CMathi::floor($progress / $s_progressResolution); if ($progressDivR != $prevProgressDivR) { $perc = CMathi::round($progressDivR * $s_progressResolution * 100); CShell::speak("{$perc}%"); } $prevProgressDivR = $progressDivR; } } CShell::speak("100%"); CShell::say("Done."); $timeoutPause->end(); }
static function construct_file_cfgs($fileName) { print "Constructing CFGs for file " . $fileName . "\n"; $file = fopen($fileName, "r"); $parser = new PhpParser\Parser(new PhpParser\Lexer()); $contents = fread($file, filesize($fileName)); $stmts = array(); try { $stmts = $parser->parse($contents); } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); } echo "There are " . count($stmts) . " statements.\n"; // Construct the CFGs for all the functions defined in // the file. echo "Constructing the CFG map of functions.\n"; $className = ""; // If there is only one statement and it's a class definition, // extract the inner class functions. if (count($stmts) == 1 && $stmts[0] instanceof PhpParser\Node\Stmt\Class_) { print "Constructing CFG for class\n"; $className = $stmts[0]->name; $function_definitions = CFG::process_function_definitions($stmts[0]->stmts, $fileName, $className); } else { $function_definitions = CFG::process_function_definitions($stmts, $fileName, $className); } $function_cfgs = $function_definitions[0]; $function_signatures = $function_definitions[1]; echo "Finished construction of the CFG map of functions.\n"; echo "Found " . count($function_signatures) . " inner functions.\n"; echo "The function names are:\n"; foreach ($function_signatures as $name => $signature) { print $name . "\n"; } // Construct the CFG of the main procedure of the file. echo "Constructing the main CFG.\n"; $main_cfg = CFG::construct_cfg($stmts); echo "Finished construction of the main CFG.\n"; echo "The main in-order traversal of the CFG is:\n"; $main_cfg->print_preorder_cfg(); /* echo "The CFGs of the inner functions are:\n"; foreach($function_cfgs as $name => $inner_cfg) { print "The CFG of ".$name." is :\n"; $inner_cfg->print_cfg(); } */ fclose($file); return new FileCFGInfo($main_cfg, $function_cfgs, $function_signatures, $className, $fileName); }
public function execute() { global $IP; $files = $this->getFiles(); $chunkSize = ceil(count($files) / 72); $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $finder = new DeprecatedInterfaceFinder(); $traverser->addVisitor($finder); $fileCount = count($files); for ($i = 0; $i < $fileCount; $i++) { $file = $files[$i]; $code = file_get_contents($file); if (strpos($code, '@deprecated') === -1) { continue; } $finder->setCurrentFile(substr($file->getPathname(), strlen($IP) + 1)); $nodes = $parser->parse($code, array('throwOnError' => false)); $traverser->traverse($nodes); if ($i % $chunkSize === 0) { $percentDone = 100 * $i / $fileCount; fprintf(STDERR, "\r[%-72s] %d%%", str_repeat('#', $i / $chunkSize), $percentDone); } } fprintf(STDERR, "\r[%'#-72s] 100%%\n", ''); // Colorize output if STDOUT is an interactive terminal. if (posix_isatty(STDOUT)) { $versionFmt = "\n* Deprecated since [37;1m%s[0m:\n"; $entryFmt = " %s [33;1m%s[0m (%s:%d)\n"; } else { $versionFmt = "\n* Deprecated since %s:\n"; $entryFmt = " %s %s (%s:%d)\n"; } foreach ($finder->getFoundNodes() as $version => $nodes) { printf($versionFmt, $version); foreach ($nodes as $node) { printf($entryFmt, $node['hard'] ? '+' : '-', $node['name'], $node['filename'], $node['line']); } } printf("\nlegend:\n -: soft-deprecated\n +: hard-deprecated (via wfDeprecated())\n"); }
/** * @param string $code * @param bool $fix * * @return ResultCollection of linting errors */ public function lint(string $code) : ResultCollection { $ast = $this->parser->parse($code); $this->fixedAst = $this->traverser->traverse($ast); return $this->linterVisitor->getCollection(); }
public function doAfterSave($withRelation = true) { $pk = $this->tableSchema->primaryKey; if ($this->isNewRecord) { $this->{$pk} = $this->dbConnection->getLastInsertID(); ## this is hack ## UPDATE AUDIT TRAIL 'CREATE' ID if (!!Yii::app()->user && !Yii::app()->user->isGuest) { $a = $this->dbConnection->createCommand("\n update p_audit_trail set model_id = :model_id\n WHERE user_id = :user_id and\n model_class = :model_class and\n type = 'create' and\n model_id is null")->execute(['model_class' => ActiveRecord::baseClass($this), 'model_id' => $this->{$pk}, 'user_id' => Yii::app()->user->id]); } } else { $this->deleteResetedRelations(); } if ($withRelation) { foreach ($this->__relations as $k => $new) { if ($k == 'currentModel') { $rel = new CHasManyRelation('currentModel', get_class($this), 'id'); } else { $rel = $this->getMetaData()->relations[$k]; } $relClass = $rel->className; if (!class_exists($relClass)) { continue; } $relType = get_class($rel); $relForeignKey = $rel->foreignKey; $relTableModel = $relClass::model(); $relTable = $relTableModel->tableName(); $relPK = $relTableModel->metadata->tableSchema->primaryKey; switch ($relType) { case 'CHasOneRelation': case 'CBelongsToRelation': if (!empty($new)) { $relForeignKey = $rel->foreignKey; if ($this->{$relForeignKey} == $new[$relPK]) { $model = $relClass::model()->findByPk($this->{$relForeignKey}); if (is_null($model)) { $model = new $relClass(); } if (array_diff($model->attributes, $new)) { $model->attributes = $new; if ($relType == 'CHasOneRelation') { $model->{$relForeignKey} = $this->{$pk}; } $model->save(); } } else { $this->loadRelation($rel->name); } } break; case 'CManyManyRelation': case 'CHasManyRelation': ## if relation type is Many to Many, prepare required variable $relMM = []; if ($relType == 'CManyManyRelation') { $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $stmts = $parser->parse('<?php ' . $relForeignKey . ';'); if (count($stmts) > 0) { $relMM = ['tableName' => $stmts[0]->name->parts[0], 'from' => $stmts[0]->args[0]->value->name->parts[0], 'to' => $stmts[0]->args[1]->value->name->parts[0]]; } } ## Handle Insert if (isset($this->__relInsert[$k])) { if ($k != 'currentModel') { if (is_string($relForeignKey)) { ## without through if ($relType != 'CManyManyRelation') { foreach ($this->__relInsert[$k] as $n => $m) { $this->__relInsert[$k][$n][$relForeignKey] = $this->{$pk}; } } } else { if (is_array($relForeignKey)) { ## with through foreach ($this->__relInsert[$k] as $n => $m) { foreach ($relForeignKey as $rk => $fk) { $this->__relInsert[$k][$n][$fk] = $this->__relations[$rel->through][$rk]; } } } } } if (count($this->__relInsert[$k]) > 0) { if ($relType == "CHasManyRelation") { ActiveRecord::batchInsert($relClass, $this->__relInsert[$k]); } ## if current relation is many to many if ($relType == 'CManyManyRelation' && !empty($relMM)) { $manyRel = []; foreach ($this->__relInsert[$k] as $item) { $manyRel[] = [$relMM['from'] => $this->{$pk}, $relMM['to'] => $item[$relPK]]; } ## if relinsert is already exist, then do not insert it again foreach ($this->__relInsert[$k] as $insIdx => &$ins) { if (!!@$ins[$relPK]) { unset($this->__relInsert[$k]); } } ActiveRecord::batchInsert($relClass, $this->__relInsert[$k]); ## create transaction entry to link between ## related model and current model ActiveRecord::batchInsert($relMM['tableName'], $manyRel, false); } } $this->__relInsert[$k] = []; } ## Handle Update if (isset($this->__relUpdate[$k])) { if ($k != 'currentModel') { if (is_string($relForeignKey)) { ## without through if ($relType == 'CManyManyRelation') { } else { foreach ($this->__relUpdate[$k] as $n => $m) { $this->__relUpdate[$k][$n][$relForeignKey] = $this->{$pk}; } } } else { if (is_array($relForeignKey)) { ## with through foreach ($this->__relUpdate[$k] as $n => $m) { foreach ($relForeignKey as $rk => $fk) { $this->__relUpdate[$k][$n][$fk] = $this->__relations[$rel->through][$rk]; } } } } } if (count($this->__relUpdate[$k]) > 0) { ActiveRecord::batchUpdate($relClass, $this->__relUpdate[$k]); } $this->__relUpdate[$k] = []; } ## Handle Delete if (isset($this->__relDelete[$k])) { if (count($this->__relDelete[$k]) > 0) { if ($relType == 'CManyManyRelation') { if (!empty($relMM)) { //first remove entry in transaction table first ActiveRecord::batchDelete($relMM['tableName'], $this->__relDelete[$k], ['table' => $relMM['tableName'], 'pk' => $relPK, 'condition' => "{$relMM['from']} = {$this->{$pk}} AND {$relMM['to']} IN (:ids)", 'integrityError' => false]); //and then remove entry in actual table //ActiveRecord::batchDelete($relClass, $this->__relDelete[$k]); } } else { ActiveRecord::batchDelete($relClass, $this->__relDelete[$k]); } } $this->__relDelete[$k] = []; } break; } } } ## handling untuk file upload if (method_exists($this, 'getFields')) { $fb = FormBuilder::load(get_class($this)); $uploadFields = $fb->findAllField(['type' => 'UploadFile']); $attrs = []; $model = $this; foreach ($uploadFields as $k => $f) { if (@$f['name'] == '' || @$f['uploadPath'] == '') { continue; } ## create directory ## Jika disini gagal, berarti ada yang salah dengan format uploadPath di FormBuilder-nya $evalDir = ''; eval('$evalDir = "' . $f['uploadPath'] . '";'); $evalDir = str_replace(["\n", "\r"], "", $evalDir); $repopath = realpath(Yii::getPathOfAlias("repo")); $evalDirArr = explode("/", $evalDir); foreach ($evalDirArr as $i => $j) { $evalDirArr[$i] = preg_replace('/[\\/\\?\\:\\*\\"\\<\\>\\|\\\\]*/', "", $j); } $evalDir = implode("/", $evalDirArr); $dir = $repopath . "/" . $evalDir . "/"; $dir = str_replace(["\n", "\r"], "", $dir); if (!is_dir($dir)) { mkdir($dir, 0777, true); } ## get oldname $old = $this->{$f['name']}; $ext = pathinfo($old, PATHINFO_EXTENSION); $filename = pathinfo($old, PATHINFO_FILENAME); if (@$f['filePattern']) { ## get newname ## Jika disini gagal, berarti ada yang salah dengan format filePattern di FormBuilder-nya eval('$newname = "' . $f['filePattern'] . '";'); } else { $newname = $filename . "." . $ext; } $new = $dir . preg_replace('/[\\/\\?\\:\\*\\"\\<\\>\\|\\\\]*/', "", $newname); $new = str_replace(["\n", "\r"], "", $new); ## delete file if already exist and allowed to overwrite if (is_file($new) && $f['allowOverwrite'] == 'Yes' && is_file($old)) { unlink($new); } if (!is_file($new) && is_file($old)) { rename($old, $new); $this->{$f['name']} = trim($evalDir, "/") . "/" . $newname; $attrs[] = $f['name']; } } if (count($attrs) > 0) { if ($this->isNewRecord) { $this->isNewRecord = false; $this->updateByPk($this->id, $this->getAttributes($attrs)); $this->isNewRecord = true; } else { $this->update($attrs); } } } return true; }
/** * Parses source code and returns the built graph. * * @param array $source_paths paths containing source code. * @param bool $remove_unreferenced_nodes should nodes with no edges be pruned from the graph as well? * @return GraphBuilder built graph. */ public static function build_graph(array $source_paths, $remove_unreferenced_nodes) { $visitor = new self(); $parser = new \PhpParser\Parser(new \PhpParser\Lexer()); $traverser = new \PhpParser\NodeTraverser(); $traverser->addVisitor($visitor); foreach ($source_paths as $source_path) { foreach (walk_path(realpath($source_path), '/\\.php$/') as $file_path) { $visitor->change_file($file_path); $code = file_get_contents($file_path); try { $statements = $parser->parse($code); $traverser->traverse($statements); } catch (\PhpParser\Error $ex) { error_log("Parse Error in {$file_path}: {$ex->getMessage()}"); } } } $visitor->prune($remove_unreferenced_nodes); return $visitor; }
$text = $comment->getText(); if (strpos($text, '@since') === false && strpos($text, '@deprecated') === false) { $this->errors[] = '@since or @deprecated tag is needed in PHPDoc for ' . $this->namespace . '\\' . $this->className . '::' . $node->name; return; } } } public function getErrors() { return $this->errors; } } echo 'Parsing all files in lib/public for the presence of @since or @deprecated on each method...' . PHP_EOL . PHP_EOL; $parser = new PhpParser\Parser(new PhpParser\Lexer()); /* iterate over all .php files in lib/public */ $Directory = new RecursiveDirectoryIterator(dirname(__DIR__) . '/lib/public'); $Iterator = new RecursiveIteratorIterator($Directory); $Regex = new RegexIterator($Iterator, '/^.+\\.php$/i', RecursiveRegexIterator::GET_MATCH); $errors = []; foreach ($Regex as $file) { $stmts = $parser->parse(file_get_contents($file[0])); $visitor = new SinceTagCheckVisitor($this->blackListedClassNames); $traverser = new \PhpParser\NodeTraverser(); $traverser->addVisitor($visitor); $traverser->traverse($stmts); $errors = array_merge($errors, $visitor->getErrors()); } if (count($errors)) { echo join(PHP_EOL, $errors) . PHP_EOL . PHP_EOL; exit(1); }
$serializer = new PhpParser\Serializer\XML(); $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver()); foreach ($files as $file) { if (strpos($file, '<?php') === 0) { $code = $file; echo "====> Code {$code}\n"; } else { if (!file_exists($file)) { die("File {$file} does not exist.\n"); } $code = file_get_contents($file); echo "====> File {$file}:\n"; } try { $stmts = $parser->parse($code); } catch (PhpParser\Error $e) { die("==> Parse Error: {$e->getMessage()}\n"); } foreach ($operations as $operation) { if ('dump' === $operation) { echo "==> Node dump:\n"; echo $dumper->dump($stmts), "\n"; } elseif ('pretty-print' === $operation) { echo "==> Pretty print:\n"; echo $prettyPrinter->prettyPrintFile($stmts), "\n"; } elseif ('serialize-xml' === $operation) { echo "==> Serialized XML:\n"; echo $serializer->serialize($stmts), "\n"; } elseif ('var-dump' === $operation) { echo "==> var_dump():\n";
function print_result() { global $minimum_stmt; global $minimum_prog; global $printer; global $tests_run; echo "***************************************************\n"; echo "****************** RESULTS ************************\n"; echo "***************************************************\n"; echo "Total test cases run : {$tests_run}\n"; if (is_null($minimum_stmt)) { echo "No minimum case found\n"; } else { echo "Minimum program found!!!!\n"; echo "\n"; $output_prog = unserialize($minimum_prog); echo $printer->prettyPrint($output_prog); echo "\n"; } } // driver try { // load code $stmts = $parser->parse($php_code); // reduction tests recursive_statement_reduce($stmts); // print test results print_result(); } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); }
public function saveRelation() { $pk = $this->tableSchema->primaryKey; foreach ($this->__relations as $k => $new) { if ($k == 'currentModel') { $rel = new CHasManyRelation('currentModel', get_class($this), $pk); } else { $rel = $this->getMetaData()->relations[$k]; } $relClass = $rel->className; if (!class_exists($relClass)) { continue; } $relType = get_class($rel); $relForeignKey = $rel->foreignKey; $relTableModel = $relClass::model(); $relTable = $relTableModel->tableName(); $relPK = $relTableModel->metadata->tableSchema->primaryKey; switch ($relType) { case 'CHasOneRelation': case 'CBelongsToRelation': if (!empty($new)) { $relForeignKey = $rel->foreignKey; if (is_array($relForeignKey)) { continue; } if ($this->{$relForeignKey} == $new[$relPK]) { $model = $relClass::model()->findByPk($this->{$relForeignKey}); if (is_null($model)) { $model = new $relClass(); } $attr = $model->getAttributesWithoutRelation(); foreach ($attr as $k => $n) { if (is_array($n)) { unset($attr[$k]); } } if (array_diff($new, $attr) || array_diff($attr, $new)) { $model->attributes = $new; if ($relType == 'CHasOneRelation') { $model->{$relForeignKey} = $this->{$pk}; } $model->save(); } } else { $this->loadRelation($rel->name); } } break; case 'CManyManyRelation': case 'CHasManyRelation': ## if relation type is Many to Many, prepare required variable $relMM = []; if ($relType == 'CManyManyRelation') { $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $stmts = $parser->parse('<?php ' . $relForeignKey . ';'); if (count($stmts) > 0) { $relMM = ['tableName' => $stmts[0]->name->parts[0], 'from' => $stmts[0]->args[0]->value->name->parts[0], 'to' => $stmts[0]->args[1]->value->name->parts[0]]; } } ## Handle Insert if (isset($this->__relInsert[$k])) { if ($k != 'currentModel') { if (is_string($relForeignKey)) { ## without through if ($relType != 'CManyManyRelation') { foreach ($this->__relInsert[$k] as $n => $m) { $this->__relInsert[$k][$n][$relForeignKey] = $this->{$pk}; } } } else { if (is_array($relForeignKey)) { ## with through foreach ($this->__relInsert[$k] as $n => $m) { foreach ($relForeignKey as $rk => $fk) { if (is_null($rel->through)) { $this->__relInsert[$k][$n][$fk] = $this->{$rk}; } else { $this->__relInsert[$k][$n][$fk] = $this->__relations[$rel->through][$rk]; } } } } } } if (count($this->__relInsert[$k]) > 0) { if ($relType == "CHasManyRelation") { ActiveRecord::batchInsert($relClass, $this->__relInsert[$k]); } ## if current relation is many to many if ($relType == 'CManyManyRelation' && !empty($relMM)) { $manyRel = []; foreach ($this->__relInsert[$k] as $item) { $manyRel[] = [$relMM['from'] => $this->{$pk}, $relMM['to'] => $item[$relPK]]; } ## if relinsert is already exist, then do not insert it again foreach ($this->__relInsert[$k] as $insIdx => &$ins) { if (!!@$ins[$relPK]) { unset($this->__relInsert[$k]); } } ActiveRecord::batchInsert($relClass, $this->__relInsert[$k]); ## create transaction entry to link between ## related model and current model ActiveRecord::batchInsert($relMM['tableName'], $manyRel, false); } } $this->__relInsert[$k] = []; } ## Handle Update if (isset($this->__relUpdate[$k])) { if ($k != 'currentModel') { if (is_string($relForeignKey)) { ## without through if ($relType == 'CHasManyRelation') { foreach ($this->__relUpdate[$k] as $n => $m) { $this->__relUpdate[$k][$n][$relForeignKey] = $this->{$pk}; } } } else { if (is_array($relForeignKey)) { ## with through foreach ($this->__relUpdate[$k] as $n => $m) { foreach ($relForeignKey as $rk => $fk) { if (is_null($rel->through)) { $this->__relUpdate[$k][$n][$fk] = $this->{$rk}; } else { $this->__relUpdate[$k][$n][$fk] = $this->__relations[$rel->through][$rk]; } } } } } } if (count($this->__relUpdate[$k]) > 0) { ActiveRecord::batchUpdate($relClass, $this->__relUpdate[$k]); ## update transaction entry to link between ## related model and current model if ($relType == 'CManyManyRelation' && !empty($relMM)) { $manyRel = []; foreach ($this->__relUpdate[$k] as $item) { $item[$relMM['from']] = $this->{$pk}; $item[$relMM['to']] = $item[$relPK]; $manyRel[] = $item; } ActiveRecord::batchUpdate($relMM['tableName'], $manyRel); } } $this->__relUpdate[$k] = []; } ## Handle Delete if (isset($this->__relDelete[$k])) { if (count($this->__relDelete[$k]) > 0) { if ($relType == 'CManyManyRelation') { if (!empty($relMM)) { //first remove entry in transaction table first ActiveRecord::batchDelete($relMM['tableName'], $this->__relDelete[$k], ['table' => $relMM['tableName'], 'pk' => $relPK, 'condition' => "{$relMM['from']} = {$this->{$pk}} AND {$relMM['to']} IN (:ids)", 'integrityError' => false]); //and then remove entry in actual table //ActiveRecord::batchDelete($relClass, $this->__relDelete[$k]); } } else { ActiveRecord::batchDelete($relClass, $this->__relDelete[$k]); } } $this->__relDelete[$k] = []; } break; } } }
public function actionPreviewSQL() { $postdata = file_get_contents("php://input"); $post = json_decode($postdata, true); $criteria = @$post['criteria'] ? $post['criteria'] : []; $params = @$post['params'] ? $post['params'] : []; $baseClass = $post['baseclass']; switch ($baseClass) { case "DataGrid": case "DataFilter": case "RelationField": case "TextField": $rel = 'currentModel'; $name = $post['rfname']; $classPath = $post['rfclass']; $modelClassPath = $post['rfmodel']; $modelClass = Helper::explodeLast(".", $modelClassPath); Yii::import($modelClassPath); $class = Helper::explodeLast(".", $classPath); Yii::import($classPath); $model = new $modelClass(); $builder = $model->commandBuilder; $fb = FormBuilder::load($classPath); $field = $fb->findField(['name' => $name]); $rf = new RelationField(); $rf->builder = $fb; $rf->attributes = $field; $rf->relationCriteria = $criteria; $rf->params = $post['params']; $criteria = $rf->generateCriteria('', []); $criteria = new CDbCriteria($criteria); break; case "DataSource": $rel = $post['rel']; $name = $post['dsname']; $classPath = $post['dsclass']; $class = Helper::explodeLast(".", $classPath); Yii::import($classPath); $model = new $class(); $builder = $model->commandBuilder; $fb = FormBuilder::load($classPath); $fb->model = new $model(); $field = $fb->findField(['name' => $name]); $ds = new DataSource(); $ds->attributes = $field; $criteria = DataSource::generateCriteria($params, $criteria, $ds); $criteria = SqlCriteria::convertPagingCriteria($criteria); $criteria = new CDbCriteria($criteria); break; } if (!isset($rel)) { echo json_encode(["sql" => '', "error" => '']); return false; } $isRelated = false; if ($rel == 'currentModel') { $tableSchema = $model->tableSchema; } else { $parent = $model::model()->find(); $relMeta = $model->getMetadata()->relations[$rel]; $relClass = $relMeta->className; if (!is_subclass_of($relClass, 'ActiveRecord')) { throw new CException("Class {$relClass} harus merupakan subclass dari ActiveRecord"); } $tableSchema = $relClass::model()->tableSchema; if (!is_null($parent)) { $parentPrimaryKey = $parent->metadata->tableSchema->primaryKey; switch (get_class($relMeta)) { case 'CHasOneRelation': case 'CBelongsToRelation': if (is_string($relMeta->foreignKey)) { $criteria->addColumnCondition([$relMeta->foreignKey => $parent->{$parentPrimaryKey}]); $isRelated = true; } break; case 'CManyManyRelation': $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $stmts = $parser->parse('<?php ' . $relMeta->foreignKey . ';'); $bridgeTable = $stmts[0]->name->parts[0]; $arg0 = $stmts[0]->args[0]->value->name->parts[0]; $arg1 = $stmts[0]->args[1]->value->name->parts[0]; $criteria->join .= " " . $relMeta->joinType . " {$bridgeTable} ON t.{$tableSchema->primaryKey} = {$bridgeTable}.{$arg1} "; break; case 'CHasManyRelation': //without through if (is_string($relMeta->foreignKey)) { $criteria->addColumnCondition([$relMeta->foreignKey => $parent->{$parentPrimaryKey}]); $isRelated = true; } //with through //todo.. break; } } } $command = $builder->createFindCommand($tableSchema, $criteria); $commandText = $command->text; if ($isRelated) { $commandText = str_replace(":ycp0", "\n" . '"{$model->' . $relMeta->foreignKey . '}"', $commandText); } $commandText = SqlFormatter::highlight($commandText); $errMsg = ''; try { $command->queryScalar(); } catch (Exception $e) { $errMsg = $e->getMessage(); $errMsg = str_replace("CDbCommand gagal menjalankan statement", "", $errMsg); } echo json_encode(["sql" => $commandText, "error" => $errMsg]); }
$node->implements = null; return $node; } } } } public function afterTraverse(array $nodes) { } } $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative()); $traverser = new PhpParser\NodeTraverser(); $prettyPrinter = new JSConverter(); $nodeDumper = new PhpParser\NodeDumper(); // resolve namespaces as fully qualified namespaces $traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver()); // we will need resolved names // add your visitor $traverser->addVisitor(new MyNodeVisitor()); try { // parse $stmts = $parser->parse(file_get_contents($argv[1])); // traverse $stmts = $traverser->traverse($stmts); // pretty print //echo "/*", $nodeDumper->dump($stmts), "\n", "*/"; #print_r($stmts); echo $prettyPrinter->prettyPrintFile($stmts); } catch (PhpParser\Error $e) { echo 'Parse Error: ', $e->getMessage(); }
<?php require 'bootstrap.php'; $parser = new PhpParser\Parser(new PhpParser\Lexer()); $nodeDumper = new PhpParser\NodeDumper(); //$file = file_get_contents("hello.php"); $file = file_get_contents($argv[1]); $flag = 0; try { $stmts = $parser->parse($file); $flag = false; if (count($stmts) == 0) { echo "No parsed statements found"; } else { echo "\n" . "{ \"data\":\n" . $nodeDumper->dump($stmts) . "}"; } } catch (PhpParser\Error $e) { echo "Error happened:" . $e->getMessage(); }