1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* StaticLoader module |
5
|
|
|
* |
6
|
|
|
* @author Alexey Krupskiy <[email protected]> |
7
|
|
|
* @link http://inji.ru/ |
8
|
|
|
* @copyright 2015 Alexey Krupskiy |
9
|
|
|
* @license https://github.com/injitools/cms-Inji/blob/master/LICENSE |
10
|
|
|
*/ |
11
|
|
|
class StaticLoader extends Module { |
12
|
|
|
|
13
|
|
|
public $mimes = []; |
14
|
|
|
|
15
|
|
|
public function init() { |
16
|
|
|
$this->mimes = $this->config['mimes']; |
17
|
|
|
} |
18
|
|
|
|
19
|
|
|
public function parsePath($path) { |
20
|
|
|
$path = Tools::parsePath($path); |
|
|
|
|
21
|
|
|
|
22
|
|
|
if (strpos($path, '/') === 0) { |
23
|
|
|
$path = substr($path, 1); |
24
|
|
|
} |
25
|
|
|
$app = substr($path, 0, strpos($path, '/')); |
26
|
|
|
|
27
|
|
|
if ($app && file_exists(INJI_SYSTEM_DIR . '/program/' . $app)) { |
28
|
|
|
$path = substr($path, strpos($path, '/') + 1); |
29
|
|
|
if (\App::$cur->name != $app) { |
30
|
|
|
$scriptApp = new App(); |
31
|
|
|
$scriptApp->name = $app; |
32
|
|
|
$scriptApp->system = true; |
33
|
|
|
$scriptApp->staticPath = "/" . $scriptApp->name . "/static"; |
34
|
|
|
$scriptApp->templatesPath = "/" . $scriptApp->name . "/static/templates"; |
35
|
|
|
$scriptApp->path = INJI_SYSTEM_DIR . '/program/' . $scriptApp->name; |
36
|
|
|
$scriptApp->type = 'app' . ucfirst(strtolower($scriptApp->name)); |
37
|
|
|
$scriptApp->installed = true; |
38
|
|
|
$scriptApp->params = []; |
39
|
|
|
$scriptApp->config = Config::app($scriptApp); |
40
|
|
|
} else { |
41
|
|
|
$scriptApp = \App::$cur; |
42
|
|
|
} |
43
|
|
|
} else { |
44
|
|
|
$scriptApp = \App::$cur->system ? \App::$primary : \App::$cur; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
if (strpos($path, 'static/') !== false && strpos($path, 'static/') <= 1) { |
48
|
|
|
$path = substr($path, strpos($path, 'static') + 7); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
$type = substr($path, 0, strpos($path, '/')); |
52
|
|
|
switch ($type) { |
53
|
|
|
case 'cache': |
54
|
|
|
return INJI_BASE_DIR . $path; |
55
|
|
|
case 'libs': |
56
|
|
|
return App::$cur->Libs->getPath(array_slice(explode('/', $path), 2)); |
57
|
|
|
case 'templates': |
58
|
|
|
$path = substr($path, strpos($path, '/') + 1); |
59
|
|
|
return $scriptApp->view->templatesPath . '/' . $path; |
60
|
|
|
case 'system': |
61
|
|
|
$path = substr($path, strpos($path, '/') + 1); |
62
|
|
|
return INJI_SYSTEM_DIR . '/static/' . $path; |
63
|
|
|
case 'moduleAsset': |
64
|
|
|
$path = substr($path, strpos($path, '/') + 1); |
65
|
|
|
if (!strpos($path, '/')) { |
66
|
|
|
return false; |
67
|
|
|
} |
68
|
|
|
$module = substr($path, 0, strpos($path, '/')); |
69
|
|
|
|
70
|
|
|
if (!$scriptApp->$module) { |
71
|
|
|
return false; |
72
|
|
|
} |
73
|
|
|
$path = substr($path, strpos($path, '/') + 1); |
74
|
|
|
if (is_callable([$module, 'staticCalled'])) { |
75
|
|
|
return $scriptApp->$module->staticCalled($path, $scriptApp->$module->path . '/static/'); |
76
|
|
|
} |
77
|
|
|
return $scriptApp->$module->path . '/static/' . $path; |
78
|
|
|
default: |
79
|
|
|
return $scriptApp->path . '/static/' . $path; |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
public function giveFile($file) { |
84
|
|
|
if (!file_exists($file) && file_exists(mb_convert_encoding($file, 'Windows-1251', 'UTF-8'))) { |
85
|
|
|
$file = mb_convert_encoding($file, 'Windows-1251', 'UTF-8'); |
86
|
|
|
} |
87
|
|
|
if (!file_exists($file)) { |
88
|
|
|
header('HTTP/1.1 404 Not Found'); |
89
|
|
|
exit(); |
|
|
|
|
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
$fileinfo = pathinfo($file); |
93
|
|
|
if (empty($fileinfo['extension'])) { |
94
|
|
|
header('HTTP/1.1 404 Not Found'); |
95
|
|
|
exit(); |
|
|
|
|
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
if (!empty($_GET['resize'])) { |
99
|
|
|
|
100
|
|
|
$allow_resize = false; |
101
|
|
|
if (App::$cur->db->connect) { |
102
|
|
|
$type = Files\Type::get($fileinfo['extension'], 'ext'); |
103
|
|
|
$allow_resize = $type ? $type->allow_resize : false; |
104
|
|
|
} |
105
|
|
|
if (!$type && in_array(strtolower($fileinfo['extension']), array('png', 'jpg', 'jpeg', 'gif'))) { |
|
|
|
|
106
|
|
|
$allow_resize = true; |
107
|
|
|
} |
108
|
|
|
if ($allow_resize) { |
109
|
|
|
|
110
|
|
|
$sizes = explode('x', $_GET['resize']); |
111
|
|
|
$sizes[0] = intval($sizes[0]); |
112
|
|
|
if (isset($sizes[1])) { |
113
|
|
|
$sizes[1] = intval($sizes[1]); |
114
|
|
|
} else { |
115
|
|
|
$sizes[1] = 0; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
if (!$sizes[0] || !$sizes[1]) { |
119
|
|
|
header('HTTP/1.1 404 Not Found'); |
120
|
|
|
exit(); |
|
|
|
|
121
|
|
|
} elseif ($sizes[0] > 2000 || $sizes[1] > 2000) { |
122
|
|
|
header('HTTP/1.1 404 Not Found'); |
123
|
|
|
exit(); |
|
|
|
|
124
|
|
|
} else { |
125
|
|
|
$dir = App::$primary->path; |
|
|
|
|
126
|
|
|
|
127
|
|
|
if (!empty($_GET['resize_crop'])) { |
128
|
|
|
if (in_array($_GET['resize_crop'], array('q', 'c'))) { |
129
|
|
|
$crop = $_GET['resize_crop']; |
130
|
|
|
} else { |
131
|
|
|
$crop = 'c'; |
132
|
|
|
} |
133
|
|
|
} elseif (!empty($_GET['resize_quadro'])) { |
134
|
|
|
$crop = 'q'; |
135
|
|
|
} else { |
136
|
|
|
$crop = ''; |
137
|
|
|
} |
138
|
|
|
$pos = 'center'; |
139
|
|
|
if (!empty($_GET['resize_pos']) && in_array($_GET['resize_pos'], array('top', 'center'))) { |
140
|
|
|
$pos = $_GET['resize_pos']; |
141
|
|
|
} |
142
|
|
|
$file = INJI_BASE_DIR . rtrim(Statics::file($file, $sizes[0] . 'x' . $sizes[1], $crop, $pos, true), '/'); |
|
|
|
|
143
|
|
|
} |
144
|
|
|
} |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
$request = getallheaders(); |
148
|
|
|
if (isset($request['If-Modified-Since'])) { |
149
|
|
|
// Разделяем If-Modified-Since (Netscape < v6 отдаёт их неправильно) |
150
|
|
|
$modifiedSince = explode(';', $request['If-Modified-Since']); |
151
|
|
|
|
152
|
|
|
// Преобразуем запрос клиента If-Modified-Since в таймштамп |
153
|
|
|
$modifiedSince = strtotime($modifiedSince[0]); |
154
|
|
|
} else { |
155
|
|
|
// Устанавливаем время модификации в ноль |
156
|
|
|
$modifiedSince = 0; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
header("Cache-control: public"); |
160
|
|
|
header("Accept-Ranges: bytes"); |
161
|
|
|
header("Pragma: public"); |
162
|
|
|
header("Content-Length: " . filesize($file)); |
163
|
|
|
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($file)) . ' GMT'); |
164
|
|
|
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 60 * 60 * 24 * 256) . ' GMT'); |
165
|
|
|
if (filemtime($file) <= $modifiedSince && (!isset($_SERVER['HTTP_CACHE_CONTROL']) || $_SERVER['HTTP_CACHE_CONTROL'] != 'no-cache')) { |
166
|
|
|
// Разгружаем канал передачи данных! |
167
|
|
|
header('HTTP/1.1 304 Not Modified'); |
168
|
|
|
exit(); |
|
|
|
|
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
header('Content-Description: File Transfer'); |
172
|
|
|
if (isset($this->mimes[strtolower($fileinfo['extension'])])) { |
173
|
|
|
header("Content-Type: " . $this->mimes[strtolower($fileinfo['extension'])]); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
if (isset($_GET['frustrate_dl']) || in_array($fileinfo['extension'], array('doc', 'docx', 'xls', 'xlsx'))) { |
177
|
|
|
|
178
|
|
|
$fileName = $fileinfo['filename'] . '.' . $fileinfo['extension']; |
179
|
|
|
if (App::$cur->db->connect) { |
180
|
|
|
$fileObj = Files\File::get(['path', '%/' . $fileinfo['filename'] . '.' . $fileinfo['extension'], 'LIKE']); |
181
|
|
|
if ($fileObj) { |
182
|
|
|
$fileName = $fileObj->original_name; |
183
|
|
|
} |
184
|
|
|
} |
185
|
|
|
header('Content-Disposition: attachment; filename="' . $fileName . '"'); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
header('Content-Transfer-Encoding: binary'); |
189
|
|
|
|
190
|
|
|
readfile($file); |
191
|
|
|
exit(); |
|
|
|
|
192
|
|
|
} |
193
|
|
|
} |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths