| 
<?phprequire 'autoload.php';
 use Redbox\Scan\Adapter;
 use Redbox\Scan\Report\Report;
 
 /**
 * First of all don't get intimidated by the number of lines in this example its mostly the database that
 * takes the numbers. In this example i will show you how to write a basic custom adapter using
 * read() and write() functions from the interface. This example will read and write it's data from a database so it can
 * be processed in index() and scan() on the ScanService.
 *
 * PS: I i do recommend you running this from a browser.
 *
 * Step 1.
 *  - Import assest/data.sql
 *
 * Step 2.
 *  - Change the database access settings
 *
 * Step 3.
 * = Run the code
 */
 
 /**
 * Let me exampling about this database class. This class is not production ready its just
 * a really simple wrapper around a sample database.
 *
 * Class Database
 */
 class Database extends \mysqli implements Adapter\AdapterInterface
 {
 CONST SCAN_ID = 1;
 
 public function __construct($host, $user, $pass, $db)
 {
 $this->connect($host, $user, $pass, $db);
 }
 
 /**
 * This class uses just one main scan record all the time. This is ID 1 (SCAN_ID) and contains the main information
 * about our scan name/date etc..
 *
 * @return array|bool
 */
 private function getScan()
 {
 $sql = sprintf("SELECT *, scandate as `date` FROM `scan` WHERE `id`='%s'", self::SCAN_ID);
 $result = $this->query($sql);
 if ($result) {
 return $result->fetch_assoc();
 }
 return false;
 }
 
 /**
 * Return the file items that have been stored prior to a scan action. These results are previously saved
 * via the write write() method.
 *
 * @return array
 */
 private function getReportItems()
 {
 $items = array();
 $sql = sprintf("SELECT * FROM `scanitems` WHERE `scanid`='%s'", self::SCAN_ID);
 $result = $this->query($sql);
 if ($result) {
 while ($item = $result->fetch_object()) {
 if (isset($items[$item->itemfolder]) === false)
 $items[$item->itemfolder] = array();
 
 $items[$item->itemfolder][$item->itemname] = $item->md5hash;
 }
 }
 return $items;
 }
 
 /**
 * Read the previous scan results from the file system.
 *
 * @return bool|Report
 */
 public function read() {
 $scan = $this->getScan();
 if (is_array($scan) === true) {
 $scan['items'] = $this->getReportItems();
 return Report::fromArray($scan);
 }
 return false;
 }
 
 /**
 * Write the report to the filesystem so we can reuse it
 * at a later stace when we invoke Redbox\Scan\ScanService's scan() method.
 *
 * @param Report|null $report
 * @return bool
 */
 public function write(Report $report = null) {
 
 if ($report) {
 $scandata = array(
 'name' => $report->getName(),
 'path' => $report->getPath(),
 );
 
 /* Step 1. Update the scan. */
 $sql = sprintf("UPDATE `scan` SET `name`='%s', `path`='%s', `scandate`=NOW()", $this->real_escape_string($scandata['name']), $this->real_escape_string($scandata['path']));
 $this->query($sql);
 
 if ($this->affected_rows > 0) {
 $items = $report->getItems();
 if (count($items) > 0) {
 
 /* Step 2. Delete old items */
 $sql = sprintf("DELETE FROM `scanitems` WHERE `scanid`='%s'", self::SCAN_ID);
 $this->query($sql);
 
 
 /* Step 3. Insert the new items */
 foreach($items as $path => $item) {
 foreach ($item as $filename => $md5hash) {
 $sql = sprintf("INSERT INTO `scanitems` SET `scanid`='%s', `itemfolder`='%s', `itemname`='%s', `md5hash`='%s'",
 self::SCAN_ID,
 $this->real_escape_string($path),
 $this->real_escape_string($filename),
 $this->real_escape_string($md5hash)
 
 );
 $this->query($sql);
 }
 }
 }
 }
 return false;
 }
 return false;
 }
 
 }
 
 if (class_exists('mysqli')) {
 
 try {
 
 $path = dirname(__FILE__)."/assets";
 $tmpfile  = $path.'/new.tmp';
 $timefile = $path.'/time.txt';
 
 $databaseAdapter = new Database(
 "localhost",
 "root",
 "root",
 "scan"
 );
 
 /**
 * Oke lets instantiate a new service and scan the assets folder inside
 * our current folder and write the data.yml file to the filesystem using the Filesystem adapter.
 */
 $scan = new Redbox\Scan\ScanService($databaseAdapter);
 if ($scan->index($path, 'Basic scan', date("Y-m-d H:i:s"))) {
 throw new Exception('Writing datafile failed.');
 }
 
 /**
 * After indexing the directory let's create a new file and update an other so
 * we can see if the filesystem picks it up.
 */
 file_put_contents($tmpfile,'Hello world');
 file_put_contents($timefile, time());
 
 
 /**
 * Oke the changes have been made lets scan the assets directory again for changes.
 */
 $report = $scan->scan();
 
 /**
 * Revert our actions.
 */
 unlink($tmpfile);
 
 /**
 * Output the changes since index action.
 */
 if(php_sapi_name() == "cli") {
 
 echo "New files\n\n";
 foreach ($report->getNewfiles() as $file) {
 echo $file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath())."\n";
 }
 
 echo "\nModified Files\n\n";
 foreach ($report->getModifiedFiles() as $file) {
 echo $file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath())."\n";
 }
 echo "\n";
 
 } else {
 
 echo '<h1>New files</h1>';
 foreach ($report->getNewfiles() as $file) {
 echo '<li>'.$file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath()).'</li>';
 }
 echo '</ul>';
 
 echo '<h1>Modified Files</h1>';
 foreach ($report->getModifiedFiles() as $file) {
 echo '<li>'.$file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath()).'</li>';
 }
 echo '</ul>';
 }
 
 } catch (Exception $e) {
 print '<pre>';
 print_r($e);
 print '</pre>';
 }
 
 } else {
 die('This example requires mysqli to be loaded.');
 }
 |