RecursiveFilterIterator版PIND

id:balibali:20080511:1210523675 の続き。RecursiveFilterIteratorを使ってみました。いろいろ適当すぎですが、とりあえず晒してみまふ。

<?php
define('SCRIPT_BASE_DIR', realpath(dirname(__FILE__)));
define('LIBRARY_PATH', SCRIPT_BASE_DIR . '/libs/');

set_include_path(LIBRARY_PATH);

require_once 'Console/Color.php';
require_once 'Console/CommandLine.php';

$parser = Console_CommandLine::fromXmlFile(SCRIPT_BASE_DIR . '/info.xml');
try {
    $result = $parser->parse();

    $search = $result->args['search'];

    $patterns = explode(';', $result->options['pattern']);
    $dirname = realpath($result->options['directory']);
} catch (Exception $e) {
    $parser->displayError($e->getMessage());
    exit;
}

$iterator = new RecursiveIteratorIterator(new PindRecursiveFilterIterator($dirname, $patterns));
$iterator->rewind();

$color = new Console_Color();

foreach ($iterator as $path => $info) {
    $result = '';

    $file = $info->openFile();
    foreach ($file as $key => $line) {
        if (strpos($line, $search) !== false) {
            $line = str_replace($search, "%3%k{$search}%n", $line);
            $result .= sprintf('%d:%s', $key + 1, $line);
        }
    }

    if ($result) {
        echo $color->convert("%G{$path}%n\n{$result}\n");
    }
}

class PindRecursiveFilterIterator extends RecursiveFilterIterator
{
    private $patterns;

    function __construct($path, $patterns = array())
    {
        parent::__construct(new RecursiveDirectoryIterator($path));
        $this->patterns = $patterns;
    }

    function accept()
    {
        $iterator = $this->getInnerIterator();
        $filename = $iterator->getFilename();

        if (strpos($filename, '.') === 0) {
            return false;
        }

        if ($iterator->isDir()) {
            return true;
        }

        foreach ($this->patterns as $pattern) {
            if (fnmatch($pattern, $filename)) {
                return true;
            }
        }
        return false;
    }

    function getChildren()
    {
        return new PindRecursiveFilterIterator($this->key(), $this->patterns);
    }
}