source: trunk/Common/Form/Form.php@ 914

Last change on this file since 914 was 914, checked in by chronos, 4 years ago
  • Added: Made IS dashboard numbers as links with filters.
File size: 19.8 KB
Line 
1<?php
2
3include_once(dirname(__FILE__).'/Types/Type.php');
4
5/*
6Form item type definition:
7Type - identifikace typu z podporovaných
8Caption - popisek, titulek položky
9Default - výchozí hodnota
10Null - hodnota nemusí být zadána
11NotInList - sloupec neviditelný v seznamu položek
12Hidden - neviditelný, při přidání nové položky se použije výchozí hodnota.
13Filter - column is used as filer according default value
14Suffix - text za hodnotou
15Description - popis významu položky
16ReadOnly - je položky pouze pro čtení
17Required - položka je vyžadována
18SQL - SQL dotaz pro zjištění hodnoty, #Id bude nahrazeno Id aktuální položky
19*/
20
21
22class Form
23{
24 public FormManager $FormManager;
25 public Database $Database;
26 public array $Definition;
27 public array $Values;
28 public array $ValuesValidate;
29 public array $ValuesFilter;
30 public string $OnSubmit;
31
32 function __construct(FormManager $FormManager)
33 {
34 $this->FormManager = &$FormManager;
35 $this->Database = $FormManager->Database;
36 $this->Definition = array();
37 $this->Values = array();
38 $this->ValuesFilter = array();
39 $this->ValuesValidate = array();
40 $this->OnSubmit = '';
41 }
42
43 function LoadDefaults(): void
44 {
45 foreach ($this->Definition['Items'] as $Index => $Item)
46 {
47 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
48 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
49 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
50 {
51 if (!array_key_exists($Index, $this->Values))
52 {
53 if (isset($Item['Default'])) $this->Values[$Index] = $Item['Default'];
54 else $this->Values[$Index] = null;
55 }
56 }
57 }
58 }
59
60 function SetClass(string $Name): void
61 {
62 $this->Definition = &$this->FormManager->Classes[$Name];
63 $this->LoadDefaults();
64 }
65
66 function GetValue(string $Index, string $Event = 'OnView'): string
67 {
68 $Item = $this->Definition['Items'][$Index];
69 if (array_key_exists($Item['Type'], $this->FormManager->FormTypes))
70 {
71 if (!array_key_exists($Item['Type'], $this->FormManager->Type->TypeDefinitionList))
72 $this->FormManager->Type->RegisterType($Item['Type'], '', $this->FormManager->FormTypes[$Item['Type']]);
73 if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Reference')
74 $UseType = 'OneToMany';
75 else if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Enumeration')
76 $UseType = 'Enumeration';
77 } else $UseType = $Item['Type'];
78 return $this->FormManager->Type->ExecuteTypeEvent($UseType, $Event,
79 array('Value' => $this->Values[$Index], 'Name' => $Index,
80 'Type' => $Item['Type'], 'Values' => $this->Values,
81 'Filter' => $this->Values[$Index]));
82 }
83
84 function ShowViewForm(): string
85 {
86 $Table = array(
87 //'Header' => array('Položka', 'Hodnota'),
88 'Rows' => array(),
89 );
90 foreach ($this->Definition['Items'] as $Index => $Item)
91 if (!array_key_exists('Hidden', $Item) or ($Item['Hidden'] == false))
92 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
93 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
94 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
95 {
96 if (array_key_exists($Item['Type'], $this->FormManager->FormTypes))
97 {
98 if (!array_key_exists($Item['Type'], $this->FormManager->Type->TypeDefinitionList))
99 $this->FormManager->Type->RegisterType($Item['Type'], '', $this->FormManager->FormTypes[$Item['Type']]);
100 if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Reference')
101 $UseType = 'OneToMany';
102 else if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Enumeration')
103 $UseType = 'Enumeration';
104 } else $UseType = $Item['Type'];
105 $Edit = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnView',
106 array('Value' => $this->Values[$Index], 'Name' => $Index,
107 'Type' => $Item['Type'], 'Values' => $this->Values,
108 'Filter' => $this->ValuesFilter[$Index]));
109 if (array_key_exists('Suffix', $Item)) $Edit .= ' '.$Item['Suffix'];
110 if (!$this->FormManager->Type->IsHidden($UseType))
111 array_push($Table['Rows'], array($Item['Caption'].':', $Edit));
112 }
113 $Output = '<fieldset><legend>'.$this->Definition['Title'].'</legend>'.Table($Table).
114 '</fieldset>';
115 return $Output;
116 }
117
118 function ShowEditForm(): string
119 {
120 if (!array_key_exists('SubmitText', $this->Definition)) $this->Definition['SubmitText'] = 'Uložit';
121 $Output = '<form enctype="multipart/form-data" class="Form" action="'.$this->OnSubmit.'" method="post">'.$this->ShowEditBlock().
122 '<div><input name="submit" type="submit" value="'.$this->Definition['SubmitText'].'" /> '.
123 '<input type="button" value="Zrušit" onclick="location.href=\'?\'"/></div></form>';
124 return $Output;
125 }
126
127 function ShowEditBlock(string $Context = ''): string
128 {
129 $Hidden = '';
130 $IsHidden = false;
131 $Table = array(
132 //'Header' => array('Položka', 'Hodnota'),
133 'Rows' => array(),
134 );
135 if ($Context != '') $Context = $Context.'-';
136 foreach ($this->Definition['Items'] as $Index => $Item)
137 {
138 if (!array_key_exists('ReadOnly', $Item)) $Item['ReadOnly'] = false;
139 if ($Item['ReadOnly'] == false)
140 if (!array_key_exists('Hidden', $Item) or ($Item['Hidden'] == false))
141 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
142 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
143 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
144 {
145 $Parameters = array('Value' => $this->Values[$Index], 'Name' => $Index,
146 'Type' => $Item['Type'], 'Values' => $this->Values);
147 if (array_key_exists('Null', $Item)) $Parameters['Null'] = $Item['Null'];
148 else unset($Parameters['Null']);
149 if (array_key_exists('OnPreset', $Item)) $Parameters['OnPreset'] = $Item['OnPreset'];
150 else unset($Parameters['OnPreset']);
151
152 if (array_key_exists($Item['Type'], $this->FormManager->FormTypes))
153 {
154 if (!array_key_exists($Item['Type'], $this->FormManager->Type->TypeDefinitionList))
155 $this->FormManager->Type->RegisterType($Item['Type'], '',
156 $this->FormManager->FormTypes[$Item['Type']]);
157 if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Reference')
158 {
159 $UseType = 'OneToMany';
160 } else if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Enumeration')
161 $UseType = 'Enumeration';
162 } else $UseType = $Item['Type'];
163 $Edit = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnEdit', $Parameters);
164 if (array_key_exists('Suffix', $Item)) $Edit .= $Item['Suffix'];
165
166 $Caption = $Item['Caption'].':';
167 if (array_key_exists($Index, $this->ValuesValidate) and
168 $this->ValuesValidate[$Index])
169 {
170 $Format = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'GetValidationFormat', array());
171 if ($Format != '') $Caption .= '<br/><small>'.$Format.'</small>';
172 $Caption = '<span style="color:red;">'.$Caption.'</span>';
173 }
174 if (!$this->FormManager->Type->IsHidden($UseType))
175 array_push($Table['Rows'], array($Caption, $Edit));
176 else $Hidden .= $Edit;
177 }
178 }
179 $Output = '<fieldset><legend>'.$this->Definition['Title'].'</legend>'.Table($Table).
180 $Hidden.'</fieldset>';
181 return $Output;
182 }
183
184 function LoadValuesFromDatabase(string $Id): void
185 {
186 foreach ($this->Definition['Items'] as $Index => $Item)
187 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
188 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
189 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
190 {
191 if (array_key_exists($Item['Type'], $this->FormManager->FormTypes))
192 {
193 if (!array_key_exists($Item['Type'], $this->FormManager->Type->TypeDefinitionList))
194 $this->FormManager->Type->RegisterType($Item['Type'], '',
195 $this->FormManager->FormTypes[$Item['Type']]);
196 if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Reference')
197 $UseType = 'OneToMany';
198 else if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Enumeration')
199 $UseType = 'Enumeration';
200 } else $UseType = $Item['Type'];
201 if (!array_key_exists('SQL', $Item)) $Item['SQL'] = '';
202 else $Item['SQL'] = str_replace('#Id', $Id, $Item['SQL']);
203 $Columns[] = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnFilterNameQuery',
204 array('Name' => $Index, 'Type' => $Item['Type'], 'SQL' => $Item['SQL']));
205 }
206 $Columns = implode(',', $Columns);
207 if (array_key_exists('SQL', $this->Definition))
208 $SourceTable = '('.$this->Definition['SQL'].') AS `TX`';
209 else $SourceTable = '`'.$this->Definition['Table'].'` AS `TX`';
210 $DbResult = $this->Database->query('SELECT '.$Columns.' FROM '.$SourceTable.' WHERE `TX`.`Id`='.$Id);
211 $DbRow = $DbResult->fetch_array();
212 foreach ($this->Definition['Items'] as $Index => $Item)
213 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
214 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
215 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
216 {
217 if (array_key_exists($Item['Type'], $this->FormManager->FormTypes))
218 {
219 if (!array_key_exists($Item['Type'], $this->FormManager->Type->TypeDefinitionList))
220 $this->FormManager->Type->RegisterType($Item['Type'], '',
221 $this->FormManager->FormTypes[$Item['Type']]);
222 if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Reference')
223 $UseType = 'OneToMany';
224 else if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Enumeration')
225 $UseType = 'Enumeration';
226 } else $UseType = $Item['Type'];
227 $this->Values[$Index] = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnLoadDb',
228 array('Value' => $DbRow[$Index], 'Name' => $Index,
229 'Type' => $Item['Type'], 'Values' => $this->Values));
230 $this->ValuesFilter[$Index] = $DbRow[$Index.'_Filter'];
231 }
232 }
233
234 function SaveValuesToDatabase(string $Id)
235 {
236 $Values = array();
237 foreach ($this->Definition['Items'] as $Index => $Item)
238 {
239 if (array_key_exists($Index, $this->Values))
240 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
241 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
242 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
243 {
244 $Parameters = array('Value' => $this->Values[$Index], 'Name' => $Index,
245 'Type' => $Item['Type'], 'Values' => $this->Values);
246
247 if (array_key_exists($Item['Type'], $this->FormManager->FormTypes))
248 {
249 if (!array_key_exists($Item['Type'], $this->FormManager->Type->TypeDefinitionList))
250 $this->FormManager->Type->RegisterType($Item['Type'], '',
251 $this->FormManager->FormTypes[$Item['Type']]);
252 if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Reference')
253 {
254 $UseType = 'OneToMany';
255 }
256 else if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Enumeration')
257 $UseType = 'Enumeration';
258 } else $UseType = $Item['Type'];
259 $Values[$Index] = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnSaveDb', $Parameters);
260 if (($Item['Type'] == 'Password') and ($Values[$Index] == '')) unset($Values[$Index]);
261 }
262 }
263 if ($Id == 0)
264 {
265 $Values['Id'] = $Id;
266 $DbResult = $this->Database->insert($this->Definition['Table'], $Values);
267 } else
268 $DbResult = $this->Database->update($this->Definition['Table'], 'Id='.$Id, $Values);
269 }
270
271 function LoadValuesFromForm(): void
272 {
273 $this->Values = $this->LoadValuesFromFormBlock();
274 }
275
276 function LoadValuesFromFormBlock(string $Context = ''): array
277 {
278 if ($Context != '') $Context = $Context.'-';
279 $Values = array();
280 foreach ($this->Definition['Items'] as $Index => $Item)
281 {
282 if (!array_key_exists('Hidden', $Item) or ($Item['Hidden'] == false))
283 {
284 if ((!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
285 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
286 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne'))) and
287 (!array_key_exists('ReadOnly', $Item) or
288 (array_key_exists('ReadOnly', $Item) and
289 ($Item['ReadOnly'] != true))))
290 {
291 //if (array_key_exists($Context.$Index, $_POST))
292 if (array_key_exists($Item['Type'], $this->FormManager->FormTypes))
293 {
294 if (!array_key_exists($Item['Type'], $this->FormManager->Type->TypeDefinitionList))
295 $this->FormManager->Type->RegisterType($Item['Type'], '',
296 $this->FormManager->FormTypes[$Item['Type']]);
297 $CustomType = $this->FormManager->FormTypes[$Item['Type']]['Type'];
298 if ($CustomType == 'Reference')
299 $UseType = 'OneToMany';
300 else if ($CustomType == 'Enumeration')
301 $UseType = 'Enumeration';
302 } else $UseType = $Item['Type'];
303 $Parameters = array('Name' => $Index, 'Type' => $Item['Type'], 'Values' => $this->Values);
304 if (array_key_exists('Null', $Item)) $Parameters['Null'] = $Item['Null'];
305 else unset($Parameters['Null']);
306 $Values[$Index] = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnLoad',
307 $Parameters);
308 }
309 } else
310 {
311 if (isset($Item['Default'])) {
312 if (isset($Item['Null']) and ($Item['Null'] == true))
313 $Values[$Index] = null;
314 else $Values[$Index] = $Item['Default'];
315 }
316 }
317 }
318 return $Values;
319 }
320
321 function Validate(): bool
322 {
323 $Valid = true;
324 foreach ($this->Definition['Items'] as $Index => $Item)
325 if ((!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
326 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
327 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne'))) and
328 (!array_key_exists('ReadOnly', $Item) or
329 (array_key_exists('ReadOnly', $Item) and
330 ($Item['ReadOnly'] != true))))
331 {
332 //if (array_key_exists($Context.$Index, $_POST))
333 if (array_key_exists($Item['Type'], $this->FormManager->FormTypes))
334 {
335 if (!array_key_exists($Item['Type'], $this->FormManager->Type->TypeDefinitionList))
336 $this->FormManager->Type->RegisterType($Item['Type'], '',
337 $this->FormManager->FormTypes[$Item['Type']]);
338 $CustomType = $this->FormManager->FormTypes[$Item['Type']]['Type'];
339 if ($CustomType == 'Reference')
340 $UseType = 'OneToMany';
341 else if ($CustomType == 'Enumeration')
342 $UseType = 'Enumeration';
343 } else $UseType = $Item['Type'];
344
345 $Parameters = array('Value' => $this->Values[$Index]);
346 if (array_key_exists('Null', $Item)) $Parameters['Null'] = $Item['Null'];
347 else $Parameters['Null'] = false;
348 if (!$this->FormManager->Type->ExecuteTypeEvent($UseType, 'Validate',
349 $Parameters)) {
350 $this->ValuesValidate[$Index] = true;
351 $Valid = false;
352 }
353 }
354 if ($Valid == false) throw new Exception('not validated');
355 return $Valid;
356 }
357}
358
359
360function MakeLink(string $Target, string $Title): string
361{
362 return '<a href="'.$Target.'">'.$Title.'</a>';
363}
364
365function Table(array $Table): string
366{
367 $Result = '<table class="BasicTable">';
368 if (array_key_exists('Header', $Table))
369 {
370 $Result .= '<tr>';
371 foreach ($Table['Header'] as $Item)
372 $Result .= '<th>'.$Item.'</th>';
373 $Result .= '</tr>';
374 }
375 foreach ($Table['Rows'] as $Row)
376 {
377 $Result .= '<tr>';
378 foreach ($Row as $Index => $Item)
379 {
380 if ($Index == 0) $Class = ' class="Header"'; else $Class = '';
381 $Result .= '<td'.$Class.' style="width: '.(floor(100 / count($Row))).'%">'.$Item.'</td>';
382 }
383 $Result .= '</tr>';
384 }
385 $Result .= '</table>';
386 return $Result;
387}
388
389class FormManager
390{
391 public array $Classes;
392 public array $FormTypes;
393 public Database $Database;
394 public Type $Type;
395 public string $RootURL;
396 public bool $ShowRelation;
397
398 function __construct(Database $Database)
399 {
400 $this->Database = &$Database;
401 $this->Classes = array();
402 $this->FormTypes = array();
403 $this->Type = new Type($this);
404 $this->ShowRelation = false;
405 }
406
407 function RegisterClass(string $Name, array $Class): void
408 {
409 $this->Classes[$Name] = $Class;
410 }
411
412 function UnregisterClass(string $Name): void
413 {
414 unset($this->Classes[$Name]);
415 }
416
417 function RegisterFormType(string $Name, array $Class): void
418 {
419 $this->FormTypes[$Name] = $Class;
420 }
421
422 function UnregisterFormType(string $Name): void
423 {
424 unset($this->FormTypes[$Name]);
425 }
426
427 function UpdateSQLMeta(): void
428 {
429 $this->Database->query('DELETE FROM ModelField');
430 $this->Database->query('DELETE FROM Model');
431 $this->Database->query('DELETE FROM DataType WHERE Parent IS NOT NULL');
432 $this->Database->query('DELETE FROM DataType');
433
434 foreach ($this->Type->TypeDefinitionList as $Name => $Type)
435 {
436 $DbResult = $this->Database->select('DataType', 'Id', 'Name="'.$Name.'"');
437 if ($DbResult->num_rows == 0)
438 {
439 $this->Database->insert('DataType', array('Name' => $Name,
440 'Title' => $Type['Class']));
441 } else
442 {
443 $DbRow = $DbResult->fetch_assoc();
444 $this->Database->update('DataType', 'Id='.$DbRow['Id'], array('Name' => $Name,
445 'Title' => $Type['Class']));
446 }
447 }
448
449 foreach ($this->Classes as $Class)
450 if (!array_key_exists('SQL', $Class) and ($Class['Table'] != ''))
451 {
452 if (!$this->Database->TableExists($Class['Table'])) continue;
453
454 echo($Class['Table'].'<br/>');
455 $Module = 1;
456 $DbResult = $this->Database->select('Model', 'Id', 'Name="'.$Class['Table'].'"');
457 if ($DbResult->num_rows == 0)
458 {
459 $this->Database->insert('Model', array('Name' => $Class['Table'], 'Title' => $Class['Title'], 'Module' => $Module));
460 $Model = $this->Database->insert_id;
461 } else
462 {
463 $DbRow = $DbResult->fetch_assoc();
464 $Model = $DbRow['Id'];
465 $this->Database->update('Model', 'Id='.$DbRow['Id'], array('Name' => $Class['Table'],
466 'Title' => $Class['Title'], 'Module' => $Module));
467 }
468
469 foreach ($Class['Items'] as $Name => $Field)
470 {
471 echo($Name.', ');
472 $DbResult = $this->Database->select('DataType', 'Id', 'Name="'.$Field['Type'].'"');
473 if ($DbResult->num_rows > 0)
474 {
475 $DbRow = $DbResult->fetch_assoc();
476 $Type = $DbRow['Id'];
477 } else {
478 $Type = $this->FormTypes[$Field['Type']];
479
480 // Search parent type
481 $DbResult = $this->Database->select('DataType', 'Id', 'Name="'.$Type['Type'].'"');
482 if ($DbResult->num_rows > 0)
483 {
484 $DbRow = $DbResult->fetch_assoc();
485 $ParentType = $DbRow['Id'];
486 } else $ParentType = null;
487
488 $this->Database->insert('DataType', array('Name' => $Field['Type'],
489 'Title' => '', 'Parent' => $ParentType));
490 $Type = $this->Database->insert_id;
491 }
492
493 $DbResult = $this->Database->select('ModelField', 'Id', '(Name="'.$Name.'") AND (Model='.$Model.')');
494 if ($DbResult->num_rows == 0)
495 {
496 $this->Database->insert('ModelField', array('Name' => $Name,
497 'Title' => $Field['Caption'], 'Model' => $Model, 'Type' => $Type));
498 } else
499 {
500 $DbRow = $DbResult->fetch_assoc();
501 $this->Database->update('ModelField', 'Id='.$DbRow['Id'], array('Name' => $Name,
502 'Title' => $Field['Caption'], 'Model' => $Model, 'Type' => $Type));
503 }
504 }
505 echo('<br/>');
506 }
507 }
508}
Note: See TracBrowser for help on using the repository browser.