Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 69
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
file_tracker
0.00% covered (danger)
0.00%
0 / 69
0.00% covered (danger)
0.00%
0 / 8
132
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 track_file
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 track_files
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 untrack_file
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 is_tracked
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 file_size
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 total_files
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 total_size
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 *
4 * This file is part of the phpBB Forum Software package.
5 *
6 * @copyright (c) phpBB Limited <https://www.phpbb.com>
7 * @license GNU General Public License, version 2 (GPL-2.0)
8 *
9 * For full copyright and license information, please see
10 * the docs/CREDITS.txt file.
11 *
12 */
13
14namespace phpbb\storage;
15
16use phpbb\cache\driver\driver_interface as cache;
17use phpbb\db\driver\driver_interface as db;
18use phpbb\storage\exception\storage_exception;
19
20class file_tracker
21{
22    /**
23     * Cache driver
24     * @var cache
25     */
26    protected $cache;
27
28    /**
29     * @var db
30     */
31    protected $db;
32
33    /**
34     * @var string
35     */
36    protected $storage_table;
37
38    /**
39     * Constructor
40     *
41     * @param cache            $cache
42     * @param db            $db
43     * @param string        $storage_table
44     */
45    public function __construct(cache $cache, db $db, string $storage_table)
46    {
47        $this->cache = $cache;
48        $this->db = $db;
49        $this->storage_table = $storage_table;
50    }
51
52    /**
53     * Track file in database
54     *
55     * @param string $storage    Storage name
56     * @param string $path        The target file
57     * @param int $size            Size in bytes
58     */
59    public function track_file(string $storage, string $path, int $size): void
60    {
61        $file = [
62            'file_path'        => $path,
63            'filesize'        => $size,
64        ];
65
66        $this->track_files($storage, [$file]);
67    }
68
69    /**
70     * Track files in database
71     *
72     * @param string $storage    Storage name
73     * @param array $files        Array of files to track
74     */
75    public function track_files(string $storage, array $files): void
76    {
77        $sql_ary = [];
78        foreach ($files as $file)
79        {
80            $sql_ary[] = [
81                'storage'        => $storage,
82                'file_path'        => $file['file_path'],
83                'filesize'        => $file['filesize'],
84            ];
85        }
86
87        $this->db->sql_multi_insert($this->storage_table, $sql_ary);
88
89        $this->cache->destroy('_storage_' . $storage . '_totalsize');
90        $this->cache->destroy('_storage_' . $storage . '_numfiles');
91    }
92
93    /**
94     * Untrack file
95     *
96     * @param string    $storage        Storage name
97     * @param string    $path            The target file
98     */
99    public function untrack_file(string $storage, $path): void
100    {
101        $sql_ary = [
102            'file_path'        => $path,
103            'storage'        => $storage,
104        ];
105
106        $sql = 'DELETE FROM ' . $this->storage_table . '
107            WHERE ' . $this->db->sql_build_array('DELETE', $sql_ary);
108        $this->db->sql_query($sql);
109
110        $this->cache->destroy('_storage_' . $storage . '_totalsize');
111        $this->cache->destroy('_storage_' . $storage . '_numfiles');
112    }
113
114    /**
115     * Check if a file is tracked
116     *
117     * @param string $storage    Storage name
118     * @param string $path        The file
119     *
120     * @return bool    True if file is tracked
121     */
122    public function is_tracked(string $storage, string $path): bool
123    {
124        $sql_ary = [
125            'file_path'        => $path,
126            'storage'        => $storage,
127        ];
128
129        $sql = 'SELECT file_id
130            FROM ' .  $this->storage_table . '
131            WHERE ' . $this->db->sql_build_array('SELECT', $sql_ary);
132        $result = $this->db->sql_query($sql);
133        $row = $this->db->sql_fetchrow($result);
134        $this->db->sql_freeresult($result);
135
136        return $row !== false;
137    }
138
139    /**
140     * Get file size in bytes
141     *
142     * @param string $path The file
143     *
144     * @return int Size in bytes.
145     *
146     * @throws storage_exception When unable to retrieve file size
147     */
148    public function file_size(string $storage, string $path): int
149    {
150        $sql_ary = [
151            'file_path'        => $path,
152            'storage'        => $storage,
153        ];
154
155        $sql = 'SELECT filesize
156            FROM ' .  $this->storage_table . '
157            WHERE ' . $this->db->sql_build_array('SELECT', $sql_ary);
158        $result = $this->db->sql_query($sql);
159        $row = $this->db->sql_fetchrow($result);
160        $this->db->sql_freeresult($result);
161
162        return (int) $row['filesize'];
163    }
164
165    /**
166     * Get number of tracked storage files for a storage
167     *
168     * @param string $storage Storage name
169     *
170     * @return int    Number of files
171     */
172    public function total_files(string $storage): int
173    {
174        $number_files = $this->cache->get('_storage_' . $storage. '_numfiles');
175
176        if ($number_files === false)
177        {
178            $sql = 'SELECT COUNT(file_id) AS numfiles
179                FROM ' .  $this->storage_table . "
180                WHERE storage = '" . $this->db->sql_escape($storage) . "'";
181            $result = $this->db->sql_query($sql);
182
183            $number_files = $this->db->sql_fetchfield('numfiles');
184            $this->cache->put('_storage_' . $storage . '_numfiles', $number_files);
185
186            $this->db->sql_freeresult($result);
187        }
188
189        return (int) $number_files;
190    }
191
192    /**
193     * Get total storage size
194     *
195     * @param string $storage Storage name
196     *
197     * @return float    Size in bytes
198     */
199    public function total_size(string $storage): float
200    {
201        $total_size = $this->cache->get('_storage_' . $storage . '_totalsize');
202
203        if ($total_size === false)
204        {
205            $sql = 'SELECT SUM(filesize) AS totalsize
206                FROM ' .  $this->storage_table . "
207                WHERE storage = '" . $this->db->sql_escape($storage) . "'";
208            $result = $this->db->sql_query($sql);
209
210            $total_size = $this->db->sql_fetchfield('totalsize');
211            $this->cache->put('_storage_' . $storage . '_totalsize', $total_size);
212
213            $this->db->sql_freeresult($result);
214        }
215
216        return (float) $total_size;
217    }
218}