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