PHP Classes

PHP Search String in File: Search for files with a given string using grep

Recommend this page to a friend!
  Info   View files Example   Demos   View files View files (58)   DownloadInstall with Composer Download .zip   Reputation   Support forum   Blog    
Ratings Unique User Downloads Download Rankings
StarStarStarStar 71%Total: 326 This week: 1All time: 7,169 This week: 89Up
Version License PHP version Categories
searchstringindirect 1.0.3The PHP License5PHP 5, Files and Folders, Searching, U...
Collaborate with this project 

Author

Description

This class can search for files with a given string using grep.

It can take a given string and performs a search using the grep command on files inside a given directory that may contain that string.

The grep command may take custom options, so it may perform searches on directories recursively.

Certain files specified in a class array variable may be ignored and not be returned in the results.

Innovation Award
PHP Programming Innovation award winner
August 2016
Winner


Prize: SourceGuarding PHP encoder tool
Searching for the contents of files in PHP is easy. However it can be slow when you need to search for data in many files.

This class provides an alternative that can be faster by using the grep command that is available in most Unix or Linux distributions, so it can search many files at once traversing directories recursively.

Manuel Lemos
Picture of Truong Van Phu
  Performance   Level  
Name: Truong Van Phu is available for providing paid consulting. Contact Truong Van Phu .
Classes: 3 packages by
Country: Viet Nam Viet Nam
Age: 34
All time rank: 271512 in Viet Nam Viet Nam
Week rank: 91 Up1 in Viet Nam Viet Nam Up
Innovation award
Innovation award
Nominee: 1x

Winner: 1x

Example

<?php
   
if ($_SERVER['REQUEST_METHOD'] == "POST") {
        if (isset(
$_POST['submit'])) {
            if (isset(
$_POST['searchString']) && $_POST['searchString'] != '') {
               
$search_string = $_POST['searchString'];
                require_once
'SearchStringInDirectory.php';
               
$searchHandle = new SearchStringInDirectory('/jquery-upload-file/server/php/files');
               
$files = $searchHandle->search($search_string);
            }
        }
    }
    function
getLineNumbers($string, $file)
    {
        return
shell_exec('grep -nir "'.$string.'" "'.$file.'"');
    }
?>

<!DOCTYPE html>
<html lang="">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Search Engine</title>

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="jquery-upload-file/css/bootstrap.min.css">
        <link rel="stylesheet" href="jquery-upload-file/css/docs.css">
        <link rel="stylesheet" href="jquery-upload-file/css/style.css">
        <!-- blueimp Gallery styles -->
        <link rel="stylesheet" href="jquery-upload-file/css/blueimp-gallery.min.css">
        <!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->
        <link rel="stylesheet" href="jquery-upload-file/css/jquery.fileupload.css">
        <link rel="stylesheet" href="jquery-upload-file/css/jquery.fileupload-ui.css">
        <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
            <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.2/html5shiv.min.js"></script>
            <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
        <![endif]-->
        <script type="text/javascript">
            var APP_URL = "<?php echo $_SERVER['HOST'].$_SERVER['REQUEST_URI'] ?>";
        </script>
        <style type="text/css" media="screen">
            table.framed.light {
                display: inline-block;
                margin-right: 15px;
            }
        </style>
    </head>
    <body>
        <div class="container-fluid" id="content">
            <div class="page-header">
              <h1 class="text-center"> Search Engine <small> Finding all files containing a text string</small></h1>
            </div>
            <div role="tabpanel">
                <!-- Nav tabs -->
                <ul class="nav nav-tabs" role="tablist" id="myTab">
                    <li role="presentation" class="">
                        <a href="#read_me" aria-controls="read_me" role="tab" data-toggle="tab">READ ME</a>
                    </li>
                    <li role="presentation" class="">
                        <a href="#search_file" aria-controls="search_file" role="tab" data-toggle="tab">SEARCH TEXT</a>
                    </li>
                    <li role="presentation">
                        <a href="#upload_file" aria-controls="upload_file" role="tab" data-toggle="tab">UPLOAD FILE</a>
                    </li>
                    <li role="presentation">
                        <a href="#voting" aria-controls="voting" role="tab" data-toggle="tab">VOTING MY PACKAGE</a>
                    </li>
                </ul>
           
                <!-- Tab panes -->
                <div class="tab-content">
                    <div role="tabpanel" class="tab-pane" id="read_me">
                        <div class="panel panel-default" style="border-top: none;border-radius: 0 0px 4px 4px;">
                            <div class="panel-body">
                                <div class="bs-callout bs-callout-warning" id="callout-third-party-libs">
                                    <h4>Upload file</h4>
                                    <p>
                                        Upload file in Upload file tab with file types <code>(TXT, DOC, PPT, XLS)</code> less than 10Mib.
                                    </p>
                                    <p>
                                        Execute command <code>chmod 0775 jquery-upload-file/server/php/files</code> OR <code>chmod 2775 jquery-upload-file/server/php/files</code> to allow upload files.
                                    </p>
                                </div>

                                <div class="bs-callout bs-callout-warning" id="callout-third-party-libs">
                                    <h4>Search text</h4>
                                    <p>
                                        Go to SEARCH TEXT, input text to search and submit.
                                    </p>
                                </div>

                                <div class="bs-callout bs-callout-warning" id="callout-third-party-libs">
                                    <h4>Notes and feature</h4>
                                    <p>
                                        Currently, the search engine apply for the file types <code>(TXT, DOC, PPT, XLS)</code>. In a future, we will improve on all the documents type.
                                    </p>
                                    <p>
                                        With the format of (DOC, PPT, XLS) files only can searching by <code>Single-byte Characters</code>
                                    </p>
                                    <p>
                                        Highlight text only apply with <code>Single-byte Characters</code> and require matches word.
                                    </p>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div role="tabpanel" class="tab-pane" id="search_file">
                        <div class="panel panel-default" style="border-top: none;border-radius: 0 0px 4px 4px;">
                            <div class="panel-body">
                                <?php
                                   
if ((isset($_POST['searchString']) && $_POST['searchString'] == '') && $_SERVER['REQUEST_METHOD'] == "POST") {
                               
?>
<div class="alert alert-danger">
                                            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                                            <strong>Error !</strong> Please enter text search and try again ...
                                        </div>
                                <?php
                                   
}
                               
?>
<?php
                                   
if ((isset($_POST['searchString']) && $_POST['searchString'] != '') && $_SERVER['REQUEST_METHOD'] == "POST" && count($files) <= 0) {
                               
?>
<div class="alert alert-warning">
                                            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                                            <strong>Results !</strong> File not matches string search ...
                                        </div>
                                <?php
                                   
}
                               
?>
<form action="" method="POST" class="form-horizontal" role="form">
                                    <div class="panel panel-default">
                                        <div class="panel-body">
                                            <div class="form-group col-lg-10">
                                                <label class="sr-only" for="searchString">Search string</label>
                                                <input type="text" value="<?php echo @($_POST['searchString']); ?>" class="form-control" name="searchString" id="searchString" placeholder="Input string">
                                            </div>
                                            <div class="form-group col-lg-2" style="text-align: center;">
                                                <button type="submit" name="submit" class="btn btn-primary" style="margin: 0 auto;">Search</button>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="panel panel-default">
                                        <table class="table table-bordered table-hover" id="myTable">
                                            <thead>
                                                <tr>
                                                    <th class="text-center">#</th>
                                                    <th class="text-center">File name</th>
                                                    <th class="text-center">File type</th>
                                                    <?php if (isset($_POST['searchString']) && $_POST['searchString'] != '') {
                                                   
?>
<th class="text-center">Matches</th>
                                                    <?php
                                                   
} ?>
<th class="text-center">Modified</th>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                <?php
                                                   
if (isset($files) && count($files)) {
                                                       
$index = 0;
                                                        foreach (
$files as $key => $file) {
                                               
?>
<tr>
                                                            <td class="text-center"><?php echo ++$index; ?></td>
                                                            <td><?php echo (str_replace(@$searchHandle->directory.'/', '', @$file->basename)); ?></td>
                                                            <td class="text-center"><?php echo @$file->extension; ?></td>
                                                            <?php if (isset($_POST['searchString']) && $_POST['searchString'] != '') {
                                                               
$lines = getLineNumbers($search_string, $file->filepath);
                                                               
$lines = explode("\n", $lines);
                                                               
$lines = array_filter($lines);
                                                                if (
count($lines) > 0) {
                                                           
?>
<td class="text-left hiliteTag">
                                                                    <?php
                                                                       
foreach ($lines as $key => $line) {
                                                                            if (
$key != 0) {
                                                                                echo
"</br>";
                                                                            }
                                                                            echo
'<span class="label label-danger badge">Line: </span> '.htmlentities(@$line).'';
                                                                            echo
"</br>";
                                                                        }
                                                                   
?>
</td>
                                                            <?php
                                                               
}
                                                            }
?>
<td class="text-center"><?php echo @$file->modified; ?></td>
                                                        </tr>
                                                <?php
                                                       
}
                                                    }
                                               
?>
</tbody>
                                        </table>
                                    </div>
                                </form>
                            </div>
                        </div>
                    </div>
                    <div role="tabpanel" class="tab-pane" id="upload_file">
                        <div class="panel panel-default" style="border-top: none;border-radius: 0 0px 4px 4px;">
                            <div class="panel-body">
                                <form id="fileupload" method="POST" enctype="multipart/form-data">
                                    <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
                                    <div class="row fileupload-buttonbar">
                                        <div class="col-lg-7">
                                            <!-- The fileinput-button span is used to style the file input field as button -->
                                            <span class="btn btn-success fileinput-button">
                                                <i class="glyphicon glyphicon-plus"></i>
                                                <span>Add files...</span>
                                                <input type="file" name="files[]" multiple>
                                            </span>
                                            <button type="submit" class="btn btn-primary start">
                                                <i class="glyphicon glyphicon-upload"></i>
                                                <span>Start upload</span>
                                            </button>
                                            <button type="reset" class="btn btn-warning cancel">
                                                <i class="glyphicon glyphicon-ban-circle"></i>
                                                <span>Cancel upload</span>
                                            </button>
                                            <button type="button" class="btn btn-danger delete">
                                                <i class="glyphicon glyphicon-trash"></i>
                                                <span>Delete</span>
                                            </button>
                                            <input type="checkbox" class="toggle">
                                            <!-- The global file processing state -->
                                            <span class="fileupload-process"></span>
                                        </div>
                                        <!-- The global progress state -->
                                        <div class="col-lg-5 fileupload-progress fade">
                                            <!-- The global progress bar -->
                                            <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
                                                <div class="progress-bar progress-bar-success" style="width:0%;"></div>
                                            </div>
                                            <!-- The extended global progress state -->
                                            <div class="progress-extended">&nbsp;</div>
                                        </div>
                                    </div>
                                    <div class="panel panel-default">
                                        <div class="panel-heading">
                                            <h3 class="panel-title">Upload Notes</h3>
                                        </div>
                                        <div class="panel-body">
                                            <ul>
                                                <li>The maximum file size for uploads in this demo is <strong><?php echo 10; ?> MiB</strong> (default file size is unlimited).</li>
                                                <li>Only file types (<strong>DOC, TXT, PPT, PDF</strong>) are allowed in this demo (by default there is no file type restriction).</li>
                                        </div>
                                    </div>
                                    <!-- The table listing the files available for upload/download -->
                                    <table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>
                                </form>
                                <!-- The template to display files available for upload -->
                                <script id="template-upload" type="text/x-tmpl">
                                {% for (var i=0, file; file=o.files[i]; i++) { %}
                                    <tr class="template-upload fade">
                                        <td>
                                            <span class="preview"></span>
                                        </td>
                                        <td>
                                            <p class="name">{%=file.name%}</p>
                                            <strong class="error text-danger"></strong>
                                        </td>
                                        <td>
                                            <p class="size">Processing...</p>
                                            <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="progress-bar progress-bar-success" style="width:0%;"></div></div>
                                        </td>
                                        <td>
                                            {% if (!i && !o.options.autoUpload) { %}
                                                <button class="btn btn-primary start" disabled>
                                                    <i class="glyphicon glyphicon-upload"></i>
                                                    <span>Start</span>
                                                </button>
                                            {% } %}
                                            {% if (!i) { %}
                                                <button class="btn btn-warning cancel">
                                                    <i class="glyphicon glyphicon-ban-circle"></i>
                                                    <span>Cancel</span>
                                                </button>
                                            {% } %}
                                        </td>
                                    </tr>
                                {% } %}
                                </script>
                                <!-- The template to display files available for download -->
                                <script id="template-download" type="text/x-tmpl">
                                {% for (var i=0, file; file=o.files[i]; i++) { %}
                                    <tr class="template-download fade">
                                        <td>
                                            <span class="preview">
                                                {% if (file.thumbnailUrl) { %}
                                                    <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img src="{%=file.thumbnailUrl%}"></a>
                                                {% } %}
                                            </span>
                                        </td>
                                        <td>
                                            <p class="name">
                                                {% if (file.url) { %}
                                                    <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>
                                                {% } else { %}
                                                    <span>{%=file.name%}</span>
                                                {% } %}
                                            </p>
                                            {% if (file.error) { %}
                                                <div><span class="label label-danger">Error</span> {%=file.error%}</div>
                                            {% } %}
                                        </td>
                                        <td>
                                            <span class="size">{%=o.formatFileSize(file.size)%}</span>
                                        </td>
                                        <td>
                                            {% if (file.deleteUrl) { %}
                                                <button class="btn btn-danger delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
                                                    <i class="glyphicon glyphicon-trash"></i>
                                                    <span>Delete</span>
                                                </button>
                                                <input type="checkbox" name="delete" value="1" class="toggle">
                                            {% } else { %}
                                                <button class="btn btn-warning cancel">
                                                    <i class="glyphicon glyphicon-ban-circle"></i>
                                                    <span>Cancel</span>
                                                </button>
                                            {% } %}
                                        </td>
                                    </tr>
                                {% } %}
                                </script>
                            </div>
                        </div>
                    </div>
                    <div role="tabpanel" class="tab-pane" id="voting">
                        <div class="panel panel-default" style="border-top: none;border-radius: 0 0px 4px 4px;">
                            <div class="panel-body">
                                <div class="pull-left">
                                    <script src="http://www.phpclasses.org/browse/package/9895/format/badge.js"> </script>
                                </div>
                                <div class="pull-left">
                                    <h3>Thank for voting</h3>
                                    <p>Please refer page <a href="http://www.phpclasses.org/vote.html" title="http://www.phpclasses.org/vote.html">http://www.phpclasses.org/vote.html</a></p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- jQuery -->
        <script src="jquery-upload-file/js/jquery.js"></script>
        <!-- Bootstrap JavaScript -->
        <script src="jquery-upload-file/js/bootstrap.min.js"></script> <!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
        <script src="jquery-upload-file/js/vendor/jquery.ui.widget.js"></script>
        <!-- The Templates plugin is included to render the upload/download listings -->
        <script src="http://blueimp.github.io/JavaScript-Templates/js/tmpl.min.js"></script>
        <!-- The Load Image plugin is included for the preview images and image resizing functionality -->
        <script src="jquery-upload-file/js/load-image.all.min.js"></script>
        <!-- The Canvas to Blob plugin is included for image resizing functionality -->
        <script src="jquery-upload-file/js/canvas-to-blob.min.js"></script>
        <!-- blueimp Gallery script -->
        <script src="jquery-upload-file/js/jquery.blueimp-gallery.min.js"></script>
        <!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
        <script src="jquery-upload-file/js/jquery.iframe-transport.js"></script>
        <!-- The basic File Upload plugin -->
        <script src="jquery-upload-file/js/jquery.fileupload.js"></script>
        <!-- The File Upload processing plugin -->
        <script src="jquery-upload-file/js/jquery.fileupload-process.js"></script>
        <!-- The File Upload image preview & resize plugin -->
        <script src="jquery-upload-file/js/jquery.fileupload-image.js"></script>
        <!-- The File Upload audio preview plugin -->
        <script src="jquery-upload-file/js/jquery.fileupload-audio.js"></script>
        <!-- The File Upload video preview plugin -->
        <script src="jquery-upload-file/js/jquery.fileupload-video.js"></script>
        <!-- The File Upload validation plugin -->
        <script src="jquery-upload-file/js/jquery.fileupload-validate.js"></script>
        <!-- The File Upload user interface plugin -->
        <script src="jquery-upload-file/js/jquery.fileupload-ui.js"></script>
        <!-- The main application script -->
        <script src="jquery-upload-file/js/main.js"></script>

        <script src="jquery-upload-file/js/hilitor.js"></script>
        <script type="text/javascript" charset="utf-8">
            $(document).ready(function () {

                <?php if (isset($search_string) && $search_string != '') {
               
?>
var myHilitor = new Hilitor("myTable");
                    myHilitor.setMatchType('open');
                      myHilitor.apply("<?php echo ($search_string) ?>");
                  <?php

               
}; ?>

                // Javascript to enable link to tab
                var url = document.location.toString();

                if (url.match('#')) {

                    $('.nav-tabs a[href="#' + url.split('#')[1] + '"]').tab('show');

                }
                else{

                    $('.nav-tabs a[href="#read_me"]').tab('show');

                }

                // Change hash for page-reload
                $('.nav-tabs a').on('shown.bs.tab', function (e) {

                    window.location.hash = e.target.hash;

                });

            });
        </script>
    </body>
</html>


Details

SearchStringInDirectory

PHP Search String In Directory

Searching for the contents of files in PHP is easy. However it can be slow when you need to search for data in many files.

This class provides an alternative that can be faster by using the grep command that is available in most Unix or Linux distributions, so it can search many files at once traversing directories recursively.

How to use 1. Require class: require_once 'SearchStringInDirectory.php'; 2. Using: $srch = new SearchStringInDirectory('/path/to/search/folder'); 3. Using: $result $srch->search("Search string");

Example code in 'index.php' file.

Thank you !

Donations

I highly appreciate any of your donations.

paypal


  Demo Search String In DirectoryExternal page  

Open in a separate window

  Files folder image Files  
File Role Description
Files folder imagejquery-upload-file (11 files, 7 directories)
Plain text file index.php Example Example script
Plain text file README.md Doc. Documentation
Plain text file SearchStringInDirectory.php Class Class source

  Files folder image Files  /  jquery-upload-file  
File Role Description
Files folder imagecors (2 files)
Files folder imagecss (10 files)
Files folder imagefonts (1 file)
Files folder imageimg (2 files)
Files folder imagejs (18 files, 2 directories)
Files folder imageserver (1 directory)
Files folder imagetest (2 files)
  Plain text file .jshintrc Data Auxiliary data
  HTML file angularjs.html Doc. Documentation
  HTML file basic-plus.html Doc. Documentation
  HTML file basic.html Doc. Documentation
  Plain text file bower.json Data Auxiliary data
  Plain text file CONTRIBUTING.md Data Auxiliary data
  Plain text file Gruntfile.js Data Auxiliary data
  HTML file index.html Doc. Documentation
  HTML file jquery-ui.html Doc. Documentation
  Plain text file package.json Data Auxiliary data
  Plain text file README.md Doc. Documentation

  Files folder image Files  /  jquery-upload-file  /  cors  
File Role Description
  HTML file postmessage.html Doc. Documentation
  HTML file result.html Doc. Documentation

  Files folder image Files  /  jquery-upload-file  /  css  
File Role Description
  Plain text file blueimp-gallery.min.css Data Auxiliary data
  Plain text file bootstrap.min.css Data Auxiliary data
  Plain text file demo-ie8.css Data Auxiliary data
  Plain text file demo.css Data Auxiliary data
  Plain text file docs.css Data Auxiliary data
  Plain text file jquery.fileupload-noscript.css Data Auxiliary data
  Plain text file jquery.fileupload-ui-noscript.css Data Auxiliary data
  Plain text file jquery.fileupload-ui.css Data Auxiliary data
  Plain text file jquery.fileupload.css Data Auxiliary data
  Plain text file style.css Data Auxiliary data

  Files folder image Files  /  jquery-upload-file  /  fonts  
File Role Description
  Plain text file glyphicons-halflings-regular.svg Data Auxiliary data

  Files folder image Files  /  jquery-upload-file  /  img  
File Role Description
  Image file loading.gif Icon Icon image
  Image file progressbar.gif Icon Icon image

  Files folder image Files  /  jquery-upload-file  /  js  
File Role Description
Files folder imagecors (2 files)
Files folder imagevendor (1 file)
  Plain text file app.js Data Auxiliary data
  Plain text file bootstrap.min.js Data Auxiliary data
  Plain text file canvas-to-blob.min.js Data Auxiliary data
  Plain text file hilitor.js Data Auxiliary data
  Plain text file jquery.blueimp-gallery.min.js Data Auxiliary data
  Plain text file jquery.fileupload-angular.js Data Auxiliary data
  Plain text file jquery.fileupload-audio.js Data Auxiliary data
  Plain text file jquery.fileupload-image.js Data Auxiliary data
  Plain text file jquery.fileupload-jquery-ui.js Data Auxiliary data
  Plain text file jquery.fileupload-process.js Data Auxiliary data
  Plain text file jquery.fileupload-ui.js Data Auxiliary data
  Plain text file jquery.fileupload-validate.js Data Auxiliary data
  Plain text file jquery.fileupload-video.js Data Auxiliary data
  Plain text file jquery.fileupload.js Data Auxiliary data
  Plain text file jquery.iframe-transport.js Data Auxiliary data
  Plain text file jquery.js Data Auxiliary data
  Plain text file load-image.all.min.js Data Auxiliary data
  Plain text file main.js Data Auxiliary data

  Files folder image Files  /  jquery-upload-file  /  js  /  cors  
File Role Description
  Plain text file jquery.postmessage-transport.js Data Auxiliary data
  Plain text file jquery.xdr-transport.js Data Auxiliary data

  Files folder image Files  /  jquery-upload-file  /  js  /  vendor  
File Role Description
  Plain text file jquery.ui.widget.js Data Auxiliary data

  Files folder image Files  /  jquery-upload-file  /  server  
File Role Description
Files folder imagephp (5 files, 1 directory)

  Files folder image Files  /  jquery-upload-file  /  server  /  php  
File Role Description
Files folder imagefiles (1 file)
  Plain text file .htaccess Data Auxiliary data
  Plain text file docker-compose.yml Data Auxiliary data
  Plain text file Dockerfile Data Auxiliary data
  Plain text file index.php Example Example script
  Plain text file UploadHandler.php Class Class source

  Files folder image Files  /  jquery-upload-file  /  server  /  php  /  files  
File Role Description
  Plain text file .htaccess Data Auxiliary data

  Files folder image Files  /  jquery-upload-file  /  test  
File Role Description
  HTML file index.html Doc. Documentation
  Plain text file test.js Data Auxiliary data

 Version Control Unique User Downloads Download Rankings  
 100%
Total:326
This week:1
All time:7,169
This week:89Up
 User Ratings  
 
 All time
Utility:90%StarStarStarStarStar
Consistency:85%StarStarStarStarStar
Documentation:85%StarStarStarStarStar
Examples:90%StarStarStarStarStar
Tests:-
Videos:-
Overall:71%StarStarStarStar
Rank:237