Completed
Push — master ( 934cdf...8f45fc )
by Johnny
01:43
created

Database::read()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 8
rs 9.4286
cc 2
eloc 6
nc 2
nop 0
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
}