1
|
|
|
<?php |
2
|
|
|
require '../vendor/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
|
|
|
$scan->index($path, 'Basic scan', date("Y-m-d H:i:s")); |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* After indexing the directory let's create a new file and update an other so |
165
|
|
|
* we can see if the filesystem picks it up. |
166
|
|
|
*/ |
167
|
|
|
file_put_contents($tmpfile,'Hello world'); |
168
|
|
|
file_put_contents($timefile, time()); |
169
|
|
|
|
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* Oke the changes have been made lets scan the assets directory again for changes. |
173
|
|
|
*/ |
174
|
|
|
$report = $scan->scan(); |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Revert our actions. |
178
|
|
|
*/ |
179
|
|
|
unlink($tmpfile); |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* Output the changes since index action. |
183
|
|
|
*/ |
184
|
|
|
if(php_sapi_name() == "cli") { |
185
|
|
|
|
186
|
|
|
echo "New files\n\n"; |
187
|
|
|
foreach ($report->getNewfiles() as $file) { |
188
|
|
|
echo $file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath())."\n"; |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
echo "\nModified Files\n\n"; |
192
|
|
|
foreach ($report->getModifiedFiles() as $file) { |
193
|
|
|
echo $file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath())."\n"; |
194
|
|
|
} |
195
|
|
|
echo "\n"; |
196
|
|
|
|
197
|
|
|
} else { |
198
|
|
|
|
199
|
|
|
echo '<h1>New files</h1>'; |
200
|
|
|
foreach ($report->getNewfiles() as $file) { |
201
|
|
|
echo '<li>'.$file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath()).'</li>'; |
202
|
|
|
} |
203
|
|
|
echo '</ul>'; |
204
|
|
|
|
205
|
|
|
echo '<h1>Modified Files</h1>'; |
206
|
|
|
foreach ($report->getModifiedFiles() as $file) { |
207
|
|
|
echo '<li>'.$file->getFilename().' '.Redbox\Scan\Filesystem\FileInfo::getFileHash($file->getRealPath()).'</li>'; |
208
|
|
|
} |
209
|
|
|
echo '</ul>'; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
} catch (Exception $e) { |
213
|
|
|
print '<pre>'; |
214
|
|
|
print_r($e); |
215
|
|
|
print '</pre>'; |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
} else { |
219
|
|
|
die('This example requires mysqli to be loaded.'); |
220
|
|
|
} |