Database   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1
Metric Value
wmc 15
lcom 1
cbo 1
dl 0
loc 110
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getReportItems() 0 15 4
A getScan() 0 9 2
A read() 0 8 2
B write() 0 40 6
1
<?php
2
require 'autoload.php';
3
use Redbox\Scan\Adapter;
4
use Redbox\Scan\Report\Report;
5
6
/**
7
 * First of all don't get intimidated by the number of lines in this example its mostly the database that
8
 * takes the numbers. In this example i will show you how to write a basic custom adapter using
9
 * read() and write() functions from the interface. This example will read and write it's data from a database so it can
10
 * be processed in index() and scan() on the ScanService.
11
 *
12
 * PS: I i do recommend you running this from a browser.
13
 *
14
 * Step 1.
15
 *  - Import assest/data.sql
16
 *
17
 * Step 2.
18
 *  - Change the database access settings
19
 *
20
 * Step 3.
21
 * = Run the code
22
 */
23
24
/**
25
 * Let me exampling about this database class. This class is not production ready its just
26
 * a really simple wrapper around a sample database.
27
 *
28
 * Class Database
29
 */
30
class Database extends \mysqli implements Adapter\AdapterInterface
31
{
32
    CONST SCAN_ID = 1;
33
34
    public function __construct($host, $user, $pass, $db)
35
    {
36
        $this->connect($host, $user, $pass, $db);
37
    }
38
39
    /**
40
     * This class uses just one main scan record all the time. This is ID 1 (SCAN_ID) and contains the main information
41
     * about our scan name/date etc..
42
     *
43
     * @return array|bool
44
     */
45
    private function getScan()
46
    {
47
        $sql = sprintf("SELECT *, scandate as `date` FROM `scan` WHERE `id`='%s'", self::SCAN_ID);
48
        $result = $this->query($sql);
49
        if ($result) {
50
            return $result->fetch_assoc();
51
        }
52
        return false;
53
    }
54
55
    /**
56
     * Return the file items that have been stored prior to a scan action. These results are previously saved
57
     * via the write write() method.
58
     *
59
     * @return array
60
     */
61
    private function getReportItems()
62
    {
63
        $items = array();
64
        $sql = sprintf("SELECT * FROM `scanitems` WHERE `scanid`='%s'", self::SCAN_ID);
65
        $result = $this->query($sql);
66
        if ($result) {
67
            while ($item = $result->fetch_object()) {
68
                if (isset($items[$item->itemfolder]) === false)
69
                    $items[$item->itemfolder] = array();
70
71
                $items[$item->itemfolder][$item->itemname] = $item->md5hash;
72
            }
73
        }
74
        return $items;
75
    }
76
77
    /**
78
     * Read the previous scan results from the file system.
79
     *
80
     * @return bool|Report
81
     */
82
    public function read() {
83
        $scan = $this->getScan();
84
        if (is_array($scan) === true) {
85
            $scan['items'] = $this->getReportItems();
86
            return Report::fromArray($scan);
87
        }
88
        return false;
89
    }
90
91
    /**
92
     * Write the report to the filesystem so we can reuse it
93
     * at a later stace when we invoke Redbox\Scan\ScanService's scan() method.
94
     *
95
     * @param Report|null $report
96
     * @return bool
97
     */
98
    public function write(Report $report = null) {
99
100
        if ($report) {
101
            $scandata = array(
102
                'name' => $report->getName(),
103
                'path' => $report->getPath(),
104
            );
105
106
            /* Step 1. Update the scan. */
107
            $sql = sprintf("UPDATE `scan` SET `name`='%s', `path`='%s', `scandate`=NOW()", $this->real_escape_string($scandata['name']), $this->real_escape_string($scandata['path']));
108
            $this->query($sql);
109
110
            if ($this->affected_rows > 0) {
111
                $items = $report->getItems();
112
                if (count($items) > 0) {
113
114
                    /* Step 2. Delete old items */
115
                    $sql = sprintf("DELETE FROM `scanitems` WHERE `scanid`='%s'", self::SCAN_ID);
116
                    $this->query($sql);
117
118
119
                    /* Step 3. Insert the new items */
120
                    foreach($items as $path => $item) {
121
                        foreach ($item as $filename => $md5hash) {
122
                            $sql = sprintf("INSERT INTO `scanitems` SET `scanid`='%s', `itemfolder`='%s', `itemname`='%s', `md5hash`='%s'",
123
                                self::SCAN_ID,
124
                                $this->real_escape_string($path),
125
                                $this->real_escape_string($filename),
126
                                $this->real_escape_string($md5hash)
127
128
                            );
129
                           $this->query($sql);
130
                        }
131
                    }
132
                }
133
            }
134
            return false;
135
        }
136
        return false;
137
    }
138
139
}
140
141
if (class_exists('mysqli')) {
142
143
    try {
144
145
        $path = dirname(__FILE__)."/assets";
146
        $tmpfile  = $path.'/new.tmp';
147
        $timefile = $path.'/time.txt';
148
149
        $databaseAdapter = new Database(
150
            "localhost",
151
            "root",
152
            "root",
153
            "scan"
154
        );
155
156
        /**
157
         * Oke lets instantiate a new service and scan the assets folder inside
158
         * our current folder and write the data.yml file to the filesystem using the Filesystem adapter.
159
         */
160
        $scan = new Redbox\Scan\ScanService($databaseAdapter);
161
        if ($scan->index($path, 'Basic scan', date("Y-m-d H:i:s"))) {
162
            throw new Exception('Writing datafile failed.');
163
        }
164
165
        /**
166
         * After indexing the directory let's create a new file and update an other so
167
         * we can see if the filesystem picks it up.
168
         */
169
        file_put_contents($tmpfile,'Hello world');
170
        file_put_contents($timefile, time());
171
172
173
        /**
174
         * Oke the changes have been made lets scan the assets directory again for changes.
175
         */
176
        $report = $scan->scan();
177
178
        /**
179
         * Revert our actions.
180
         */
181
        unlink($tmpfile);
182
183
        /**
184
         * Output the changes since index action.
185
         */
186
        if(php_sapi_name() == "cli") {
187
188
            echo "New files\n\n";
189
            foreach ($report->getNewfiles() as $file) {
190
                echo $file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath())."\n";
191
            }
192
193
            echo "\nModified Files\n\n";
194
            foreach ($report->getModifiedFiles() as $file) {
195
                echo $file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath())."\n";
196
            }
197
            echo "\n";
198
199
        } else {
200
201
            echo '<h1>New files</h1>';
202
            foreach ($report->getNewfiles() as $file) {
203
                echo '<li>'.$file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath()).'</li>';
204
            }
205
            echo '</ul>';
206
207
            echo '<h1>Modified Files</h1>';
208
            foreach ($report->getModifiedFiles() as $file) {
209
                echo '<li>'.$file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath()).'</li>';
210
            }
211
            echo '</ul>';
212
        }
213
214
    } catch (Exception $e) {
215
        print '<pre>';
216
        print_r($e);
217
        print '</pre>';
218
    }
219
220
} else {
221
    die('This example requires mysqli to be loaded.');
222
}