Skip to content

Instantly share code, notes, and snippets.

@velosipedist
Last active December 28, 2015 10:49
Show Gist options
  • Save velosipedist/7489189 to your computer and use it in GitHub Desktop.
Save velosipedist/7489189 to your computer and use it in GitHub Desktop.
Web script that exctracts 'todo' comments or all of comments from given dir. Use only on local machine! Unsafe!
<?php
//todo use composer global vendor path
require('c:\Users\user\AppData\Roaming\Composer\vendor\autoload.php');
use Underscore\Types\Arrays;
use Underscore\Types\String;
use CallbackFilterIterator as CI;
use RecursiveDirectoryIterator as DI;
use RecursiveiteratorIterator as RI;
use RecursiveRegexIterator as REI;
ini_set('error_reporting', E_ERROR | E_COMPILE_WARNING | E_COMPILE_ERROR | E_PARSE);
$start = microtime(true);
?>
<!doctype html>
<html lang="en-US">
<head>
<meta charset="<?=isset($_GET['charset']) ? $_GET['charset'] : 'UTF-8' ?>"/>
<link href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAALsBAAC7AQAAAAAAAAAAAAD///8A////AP///wAAAAABAAAAHwAAAEIAAABFAAAARQAAAEUAAABFAAAARQAAAEUAAABCAAAAHwAAAAH///8A////AP///wD///8AAAAAHwEBAb8BAQH8AQEB/wEBAf8BAQH/AQEB/wEBAf8BAQH/AQEB/AEBAb8AAAAf////AP///wD///8A////AAAAAEIODg7829vb/+3t7f/p6en/5OTk/+jo6P/l5eX/4+Pj/8/Pz/8ODg78AAAAQv///wD///8A////AP///wAAAABFGxsb/9XV1f9tbW3/SVRa/0lPUv96enr/0dHR/9u7of/i3Nf/Gxsb/wAAAEX///8A////AP///wD///8AAAAARSUlJf/4+Pj/bHZ8/z1lff/s7Oz/7e3t/+zs7P/q6ur/5+Xi/yUlJf8AAABF////AP///wD///8A////AAAAAEUlJSX/jY2N/zAwMP9TV1v/fn5+/3x8fP/W1tb/3r2i/+ji3f8lJSX/AAAARf///wD///8A////AP///wAAAABFJCQk/09PT/+AgID//f39//n5+f/19fX/8fHx/+/v7//t6+j/JSUl/wAAAEX///8A////AP///wD///8AAAAAWiEhIf9jY2P/goKC/4SEhP+EhIT/goKC/9/f3//iwab/7efi/yUlJf8AAABF////AP///wD///8AAAAACQAAAMEmJib/7e3t///////////////////////+/v7/+vr6//Ty7/8lJSX/AAAARf///wD///8A////AAAAAJQaGhrVISEh/+Xl5f+EhIT/hISE/4SEhP+EhIT/5eXl/+rJr//59PD/JSUl/wAAAEX///8A////AERERJI3NzfVDAwMgiUlJf///////////////////////////////////////fv4/yUlJf8AAABF////AP///wAEBASHREREkwAAAEIkJCT87e3t/5WVlf+VlZX/lZWV/5WVlf+VlZX/lZWV/+3t7f8kJCT8AAAAQv///wD///8A////AP///wAAAAAfGxsbvyQkJPzy8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v8kJCT8GxsbvwAAAB////8A////AP///wD///8AAAAAAQAAAB8AAABCnZ2d/+Tk5P/k5OT/5OTk/+Tk5P+dnZ3/AAAAQgAAAB8AAAAB////AP///wD///8A////AP///wD///8A////AP///wCYmJj/mJiY/5iYmP+YmJj/////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A4AEAAOABAADgAQAA4AEAAOABAADgAQAA4AEAAOABAADAAQAAwAEAAIABAACAAQAA4AEAAOABAAD+HwAA//8AAA=="
rel="icon" type="image/x-icon" />
<!-- <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootswatch/3.0.1/flatly/bootstrap.min.css">
<title>TODO</title>
<style type="text/css">
body {
font-family: segoe ui;
font-size: 13px;
line-height: 17px;
padding-top: 20px;
background: url("http://cdn.backgroundhost.com/backgrounds/subtlepatterns/subtlenet2.png");
}
pre, code {
font-family: consolas;
font-size: 12px;
line-height: 14px;
}
h1, h2, h3, h4, h5 {
font-family: segoe ui;
margin: .9em 0 4px;
line-height: 1.3em;
}
h3 {
font-size: 15px;
color: #4472b8;
}
.todos div {
}
.stopwatch{
position: fixed;
display: inline-block;
padding: 5px 8px;
background: #5c8999;
top: 5px;
right: 5px;
}
</style>
</head>
<form method="get" role="form">
<div class="container">
<div class="row">
<div class="col-md-10">
<div class="form-group">
<label>Full Path</label>
<input type="text" name="dir" value="<?= $_GET['dir'] ?>" size="60"
class="form-control dir" />
</div>
</div>
<div class="col-md-2">
<label>&nbsp;</label>
<input type="submit" value="Show TODO" class="btn btn-primary btn-block" />
</div>
</div>
<div class="form-group">
<label class="radio-inline">
<input type="radio" name="pattern" value="todo"
<? if(!$_GET['pattern'] || $_GET['pattern']=='todo') echo 'checked';?> >
TODO
</label>
<label class="radio-inline">
<input type="radio" name="pattern" value="all"
<? if($_GET['pattern']=='all') echo 'checked';?> >
All comments
</label>
&emsp;
<label class="radio-inline">
<input type="radio" name="charset" value="utf-8"
<? if(!$_GET['charset'] || $_GET['charset']=='utf-8') echo 'checked';?> >
<span class="label label-warning">UTF8</span>
</label>
<label class="radio-inline">
<input type="radio" name="charset" value="windows-1251"
<? if($_GET['charset']=='windows-1251') echo 'checked';?> >
<span class="label label-warning">Win</span>
</label>
</div>
</div>
</form>
<div class="container">
<div class="row">
<div class="todos">
<?php
try {
if (!isset($_GET['dir'])) {
throw new Exception("Enter valid dirname", -1);
}
$dir = realpath($_GET['dir']);
if ($dir === false) {
throw new Exception("Wrong dir: $dir");
}
if (!is_dir($dir)) {
throw new Exception("It is not dir: $dir");
}
$todoList = [];
$iterator = new CI(
new RI(
new REI(
new DI($dir, DI::CURRENT_AS_FILEINFO | DI::KEY_AS_FILENAME),
'@(?:^[A-Z]\w+(\.php))|(?:^[^:*?"<>|.]+)@',
REI::MATCH,
REI::USE_KEY)),
function ($item, $filename) use (&$todoList) {
if ($item->isDir() || (strtolower($item->getExtension()) != 'php')) {
return false;
}
$found = false;
/** @var SplFileInfo $item */
$sourcePath = $item->getRealPath();
$srcTokens = token_get_all(file_get_contents($sourcePath));
foreach ($srcTokens as $line => $token) {
if ($token[0] == T_COMMENT) {
$found = true;
//todo /* processing
//todo move to SPLFileIterator?
if ($_GET['pattern']=='all' || preg_match('|^//\s*todo\b|i', $token[1])) {
if (!isset($todoList[$sourcePath])) {
$todoList[$sourcePath] = [];
}
$todoList[$sourcePath][$line] = $token[1];
}
}
}
return $found;
}
);
iterator_count($iterator);
foreach ($todoList as $filename => $items) {
$filename = substr($filename, strlen($dir));
/** @var DirectoryIterator $item */
print "<h3>{$filename}</h3>";
foreach ($items as $line => $todo) {
print "<div><pre>{$line}: {$todo}</pre></p>";
}
}
} catch (Exception $e) {
if ($e->getCode() !== -1) {
print <<<HTML
<p style="color: #4f211b; padding: 4px ;background: #eeaf9b; display: inline-block;">Error: {$e->getMessage()}</p>
HTML;
} else {
print <<<HTML
<p>{$e->getMessage()}</p>
HTML;
}
}
?></div>
</div>
</div>
<div class="stopwatch label label-info">
<?=number_format(microtime(true) - $start, 3, ',',' ')?> sec
</div>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment