source: trunk/Modules/File/File.php

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