source: trunk/Modules/File/File.php@ 887

Last change on this file since 887 was 887, checked in by chronos, 4 years ago
  • Added: Static types added to almost all classes, methods and function. Supported by PHP 7.4.
  • Fixed: Various found code issues.
File size: 9.0 KB
Line 
1<?php
2
3include_once(dirname(__FILE__).'/MimeTypes.php');
4
5class File extends Model
6{
7 public string $FilesDir;
8
9 function __construct(System $System)
10 {
11 parent::__construct($System);
12 $this->FilesDir = '';
13 }
14
15 function Delete($Id): void
16 {
17 $DbResult = $this->Database->select('File', 'Name', 'Id='.$Id);
18 if ($DbResult->num_rows > 0)
19 {
20 $DbRow = $DbResult->fetch_assoc();
21 $this->Database->delete('File', 'Id='.$Id);
22 unlink($this->FilesDir.'/'.$Id.'_'.$DbRow['Name']);
23 }
24 }
25
26 function CreateFromUpload(string $Name): string
27 {
28 // Submited form with file input have to be enctype="multipart/form-data"
29 $Result = 0;
30 if (array_key_exists($Name, $_FILES) and ($_FILES[$Name]['name'] != ''))
31 {
32 if (file_exists($_FILES[$Name]['tmp_name']))
33 {
34 $FileName = substr($_FILES[$Name]['name'], strrpos($_FILES[$Name]['name'], '/'));
35 $this->Database->query('INSERT INTO File (`Name`, `Size`) VALUES ("'.$FileName.'", '.filesize($_FILES[$Name]['tmp_name']).')');
36 $InsertId = $this->Database->insert_id;
37 if (move_uploaded_file($_FILES[$Name]['tmp_name'], $this->FilesDir.'/'.$InsertId.'_'.$FileName)) $Result = $InsertId;
38 }
39 }
40 return $Result;
41 }
42
43 function DetectMimeType(string $FileName): string
44 {
45 $MimeTypes = GetMimeTypes();
46 $MimeType = pathinfo($FileName, PATHINFO_EXTENSION);
47 $Result = $MimeTypes[$MimeType][0];
48 return $Result;
49 }
50
51 function Download(string $Id): void
52 {
53 $DbResult = $this->Database->select('File', '*', 'Id='.addslashes($Id));
54 if ($DbResult->num_rows > 0)
55 {
56 $DbRow = $DbResult->fetch_assoc();
57 if ($DbRow['Directory'] != '') $FileName = $this->GetDir($DbRow['Directory']);
58 else $FileName = $this->FilesDir;
59 $FileName .= $DbRow['Name'];
60 if (file_exists($FileName))
61 {
62 Header('Content-Type: '.$this->DetectMimeType($FileName));
63 Header('Content-Disposition: inline; filename="'.$DbRow['Name'].'"');
64 echo(file_get_contents($FileName));
65 } else echo('Soubor nenalezen!');
66 } else echo('Soubor nenalezen!');
67 }
68
69 function GetDir(string $Id): string
70 {
71 $DbResult = $this->Database->select('FileDirectory', '*', 'Id='.$Id);
72 $DbRow = $DbResult->fetch_assoc();
73 if ($DbRow['Parent'] != '') $Result = $this->GetDir($DbRow['Parent']);
74 else $Result = $this->FilesDir;
75 $Result .= $DbRow['Name'].'/';
76 return $Result;
77 }
78
79 function GetFullPath(string $Id): string
80 {
81 $DbResult = $this->Database->select('File', '*', 'Id='.addslashes($Id));
82 if ($DbResult->num_rows > 0)
83 {
84 $DbRow = $DbResult->fetch_assoc();
85 if ($DbRow['Directory'] != '') $FileName = $this->GetDir($DbRow['Directory']);
86 else $FileName = $this->FilesDir;
87 $FileName .= $DbRow['Name'];
88 return $FileName;
89 } else echo('Soubor nenalezen!');
90 }
91}
92
93class PageFile extends Page
94{
95 function Show(): string
96 {
97 if (array_key_exists('id', $_GET)) $Id = $_GET['id'];
98 else if (array_key_exists('i', $_GET)) $Id = $_GET['i'];
99 else return $this->SystemMessage('Chyba', 'Nezadáno id souboru');
100 $this->ClearPage = true;
101 $Output = ModuleFile::Cast($this->System->GetModule('File'))->File->Download($Id);
102 return $Output;
103 }
104}
105
106class PageFileCheck extends Page
107{
108 function __construct(System $System)
109 {
110 parent::__construct($System);
111 $this->FullTitle = 'File check';
112 $this->ShortTitle = 'File check';
113 $this->ParentClass = 'PagePortal';
114 }
115
116 function GetAbsolutePath(string $Path): string
117 {
118 $Path = trim($Path);
119 $IsRoot = substr($Path, 0, 1) == '/';
120 $Path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $Path);
121 $Parts = array_filter(explode(DIRECTORY_SEPARATOR, $Path), 'strlen');
122 $Absolutes = array();
123 foreach ($Parts as $Part)
124 {
125 if ('.' == $Part) continue;
126 if ('..' == $Part)
127 {
128 array_pop($Absolutes);
129 } else
130 {
131 $Absolutes[] = $Part;
132 }
133 }
134 $Path = implode(DIRECTORY_SEPARATOR, $Absolutes);
135 if ($IsRoot) $Path = DIRECTORY_SEPARATOR.$Path;
136 return $Path;
137 }
138
139 function Show(): string
140 {
141 $Output = '<strong>Missing files:</strong><br>';
142 if (!ModuleUser::Cast($this->System->GetModule('User'))->User->CheckPermission('File', 'Check'))
143 return 'Nemáte oprávnění';
144 $DbResult = $this->Database->select('File', 'Id');
145 while ($DbRow = $DbResult->fetch_assoc())
146 {
147 $Id = $DbRow['Id'];
148 $FileName = $this->GetAbsolutePath(ModuleFile::Cast($this->System->GetModule('File'))->File->GetFullPath($Id));
149 if (!file_exists($FileName))
150 $Output .= '<a href="'.$this->System->Link('/is/?a=view&amp;t=File&amp;i='.$Id).'">'.$FileName.'</a><br>';
151 }
152 return $Output;
153 }
154}
155
156class ModuleFile extends AppModule
157{
158 public File $File;
159
160 function __construct(System $System)
161 {
162 parent::__construct($System);
163 $this->Name = 'File';
164 $this->Version = '1.0';
165 $this->Creator = 'Chronos';
166 $this->License = 'GNU/GPLv3';
167 $this->Description = 'Base module for file management';
168 $this->Dependencies = array('User');
169
170 $this->File = new File($this->System);
171 }
172
173 function DoInstall(): void
174 {
175 }
176
177 function DoUninstall(): void
178 {
179 }
180
181 function DoStart(): void
182 {
183 global $Config;
184
185 $this->System->RegisterPage(['file'], 'PageFile');
186 $this->System->RegisterPage(['file-check'], 'PageFileCheck');
187 $this->File->FilesDir = dirname(__FILE__).'/../../'.$Config['Web']['UploadFileFolder'];
188 $this->System->FormManager->RegisterClass('File', array(
189 'Title' => 'Soubor',
190 'Table' => 'File',
191 'Items' => array(
192 'Name' => array('Type' => 'String', 'Caption' => 'Jméno', 'Default' => ''),
193 'Directory' => array('Type' => 'TDirectory', 'Caption' => 'Adresář', 'Default' => '', 'Null' => true),
194 'Size' => array('Type' => 'Integer', 'Caption' => 'Velikost', 'Default' => ''),
195 'Time' => array('Type' => 'DateTime', 'Caption' => 'Čas vytvoření', 'Default' => ''),
196 'Invoices' => array('Type' => 'TFinanceInvoiceListFile', 'Caption' => 'Faktury', 'Default' => ''),
197 'Operations' => array('Type' => 'TFinanceOperationListFile', 'Caption' => 'Operace', 'Default' => ''),
198 'Contracts' => array('Type' => 'TContractListFile', 'Caption' => 'Smlouvy', 'Default' => ''),
199 'StockMoves' => array('Type' => 'TStockMoveListFile', 'Caption' => 'Skladové pohyby', 'Default' => ''),
200 ),
201 'ItemActions' => array(
202 array('Caption' => 'Stáhnout', 'URL' => '/file?i=#RowId'),
203 ),
204 'Actions' => array(
205 array('Caption' => 'Kontrola souborů', 'URL' => '/file-check'),
206 ),
207 ));
208 $this->System->FormManager->RegisterClass('FileDirectory', array(
209 'Title' => 'Adresář souborů',
210 'Table' => 'FileDirectory',
211 'Items' => array(
212 'Name' => array('Type' => 'String', 'Caption' => 'Jméno', 'Default' => ''),
213 'Parent' => array('Type' => 'TDirectory', 'Caption' => 'Nadřazený adresář', 'Default' => '', 'Null' => true),
214 'Files' => array('Type' => 'TFileList', 'Caption' => 'Soubory', 'Default' => ''),
215 'Subdirectories' => array('Type' => 'TDirectoryList', 'Caption' => 'Podadresáře', 'Default' => ''),
216 ),
217 ));
218 $this->System->FormManager->RegisterFormType('TDirectory', array(
219 'Type' => 'Reference',
220 'Table' => 'FileDirectory',
221 'Id' => 'Id',
222 'Name' => 'Name',
223 'Filter' => '1',
224 ));
225 $this->System->FormManager->RegisterFormType('TFile', array(
226 'Type' => 'Reference',
227 'Table' => 'File',
228 'Id' => 'Id',
229 'Name' => 'Name',
230 'Filter' => '1',
231 ));
232 $this->System->FormManager->RegisterFormType('TFileList', array(
233 'Type' => 'ManyToOne',
234 'Table' => 'File',
235 'Id' => 'Id',
236 'Ref' => 'Directory',
237 'Filter' => '1',
238 ));
239 $this->System->FormManager->RegisterFormType('TDirectoryList', array(
240 'Type' => 'ManyToOne',
241 'Table' => 'FileDirectory',
242 'Id' => 'Id',
243 'Ref' => 'Parent',
244 'Filter' => '1',
245 ));
246 $this->System->FormManager->RegisterFormType('TFinanceInvoiceListFile', array(
247 'Type' => 'ManyToOne',
248 'Table' => 'FinanceInvoice',
249 'Id' => 'Id',
250 'Ref' => 'File',
251 'Filter' => '1',
252 ));
253 $this->System->FormManager->RegisterFormType('TFinanceOperationListFile', array(
254 'Type' => 'ManyToOne',
255 'Table' => 'FinanceOperation',
256 'Id' => 'Id',
257 'Ref' => 'File',
258 'Filter' => '1',
259 ));
260 $this->System->FormManager->RegisterFormType('TContractListFile', array(
261 'Type' => 'ManyToOne',
262 'Table' => 'Contract',
263 'Id' => 'Id',
264 'Ref' => 'File',
265 'Filter' => '1',
266 ));
267 $this->System->FormManager->RegisterFormType('TStockMoveListFile', array(
268 'Type' => 'ManyToOne',
269 'Table' => 'StockMove',
270 'Id' => 'Id',
271 'Ref' => 'File',
272 'Filter' => '1',
273 ));
274 }
275
276 static function Cast(AppModule $AppModule): ModuleFile
277 {
278 if ($AppModule instanceof ModuleFile)
279 {
280 return $AppModule;
281 }
282 throw new Exception('Expected ModuleFile type but got '.gettype($AppModule));
283 }
284}
Note: See TracBrowser for help on using the repository browser.