-
Notifications
You must be signed in to change notification settings - Fork 0
/
loader.php
175 lines (162 loc) · 4.44 KB
/
loader.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<?php
/**
* @var int Items to show per page
*/
define('ITEMS_PER_PAGE', 15);
/**
* Returns a list of media files
*
* @param string $path
* @param bool $recursive
* @return array
*/
function gatherMediaFiles($path = '.', $recursive = true)
{
$files = [];
// Credit to samjco (https://stackoverflow.com/a/69920323/8428965)
$iterator = new RecursiveDirectoryIterator($path);
if ($recursive) {
$iterator = new RecursiveIteratorIterator($iterator);
}
$regex = new RegexIterator($iterator, '/^.+(.webm|.mp4|.gif|.mkv|.m4v)$/i', RecursiveRegexIterator::GET_MATCH);
foreach ($regex as $val => $regex) {
$files[] = $val;
}
return $files;
}
/**
* Returns a list of media folders
*
* @param string $path
* @return array
*/
function gatherMediaFolders(string $path = '*')
{
// Exclude assets folder
return array_diff(glob($path, GLOB_ONLYDIR), ['assets']);
}
/**
* Shuffles an array in a repeatable manner, if the same $seed is provided.
*
* @author deceze (https://stackoverflow.com/a/19658344/8428965)
* @param array &$items The array to be shuffled.
* @param integer $seed The result of the shuffle will be the same for the same input ($items and $seed). If not given, uses the current time as seed.
* @return array
*/
function seeded_shuffle(array $items, $seed = false)
{
$items = array_values($items);
mt_srand($seed ? $seed : time());
for ($i = count($items) - 1; $i > 0; $i--) {
$j = mt_rand(0, $i);
list($items[$i], $items[$j]) = array($items[$j], $items[$i]);
}
return $items;
}
/**
* Sort the files by time
*
* @param array $items The array to be sorted
* @param bool $direction Perform asc or desc sort
* @return array
*/
function sort_by_time($items, $direction = SORT_ASC)
{
foreach ($items as $file) {
$timestamps[$file] = filemtime($file);
}
array_multisort($timestamps, $direction, $items);
return $items;
}
/**
* Search an array
*
* @param string $needle
* @param array $array
* @return array
*/
function search(string $needle, array $array)
{
$input = preg_quote(ltrim($needle, '-'), '~');
$filtered = preg_filter('~' . $input . '~', '$0', $array);
if (@$needle[0] === '-') {
return array_diff($array, $filtered);
}
return $filtered;
}
/**
* Recursive search
*
* @param string $query
* @param array $array
* @return array
*/
function recursiveSearch(string $query, array $array)
{
$query = explode(' ', $query);
foreach ($query as $q) {
$array = search($q, $array);
}
return $array;
}
/**
* Get the current state metadata
*
* @param array $data
* @return array
*/
function getMetadata(array $data)
{
$count = count($data);
return [
'file_count' => (int) $count,
'current_page' => (int) ($_GET['page'] ?? 1),
'page_count' => (int) ceil($count / ITEMS_PER_PAGE),
'seed' => $_SESSION['seed'] ?? null
];
}
// Begin processing
session_start();
// Sanitize inputs
$acceptable = ['folder', 'seed', 'random', 'page', 'query'];
foreach ($acceptable as $key) {
if (isset($_GET[$key]) && @!is_string($_GET[$key])) {
die("Error 400: BAD REQUEST! {$key} parameter is malformated.");
}
}
// Gather and sort files
$files = gatherMediaFiles($_GET['folder'] ?? '.');
$folders = gatherMediaFolders();
if (isset($_GET['random'])) {
if (!isset($_GET['seed'])) {
$seed = rand(0, 999999999);
$location = "{$_SERVER['REQUEST_URI']}&seed={$seed}";
header("Location: $location");
echo "Redirecting you to $location";
die;
} else if ($_GET['seed'] !== @$_SESSION['seed']) {
if (!is_numeric($_GET['seed'])) {
die('400 Bad Request');
}
$_SESSION['seed'] = $_GET['seed'];
$_SESSION['files'] = seeded_shuffle($files, $_SESSION['seed']);
}
} else if (isset($_GET['newest'])) {
$_SESSION['files'] = sort_by_time($files, SORT_DESC);
} else if (isset($_GET['oldest'])) {
$_SESSION['files'] = sort_by_time($files, SORT_ASC);
}
$files = $_SESSION['files'] ?? $files;
// Perform query
if (isset($_GET['query'])) {
$files = recursiveSearch(htmlspecialchars($_GET['query']), $files);
}
// Finalize
$metadata = getMetadata($files);
$files = array_slice($files, ($metadata['current_page'] - 1) * ITEMS_PER_PAGE, ITEMS_PER_PAGE);
foreach ($files as $key => $file) {
$files[$key] = [
'media' => ltrim($file, '.\\'),
'type' => @end(explode('.', $file))
];
}