source: trunk/Common/Form/Form.php

Last change on this file was 983, checked in by chronos, 3 weeks ago
  • Fixed: IS form unknown items error handling.
  • Modified: Ping redirection to Inext local network.
File size: 14.0 KB
Line 
1<?php
2
3include_once(dirname(__FILE__).'/Types/Type.php');
4include_once(dirname(__FILE__).'/FormManager.php');
5
6/*
7Form item type definition:
8Type - identifikace typu z podporovaných
9Caption - popisek, titulek položky
10Default - výchozí hodnota
11Null - hodnota nemusí být zadána
12NotInList - sloupec neviditelný v seznamu položek
13Hidden - neviditelný, při přidání nové položky se použije výchozí hodnota.
14Filter - column is used as filer according default value
15Suffix - text za hodnotou
16Description - popis významu položky
17ReadOnly - je položky pouze pro čtení
18Required - položka je vyžadována
19SQL - SQL dotaz pro zjištění hodnoty, #Id bude nahrazeno Id aktuální položky
20*/
21class FormItem
22{
23 public string $Type;
24 public string $Caption;
25 public string $Default;
26 public bool $Null;
27 public bool $NotInList;
28 public bool $Hidden;
29 public bool $Filter;
30 public string $Suffix;
31 public string $Description;
32 public bool $ReadOnly;
33 public bool $Required;
34 public string $SQL;
35}
36
37class Form
38{
39 public FormManager $FormManager;
40 public Database $Database;
41 public array $Definition;
42 public array $Values;
43 public array $ValuesValidate;
44 public array $ValuesFilter;
45 public string $OnSubmit;
46
47 function __construct(FormManager $FormManager)
48 {
49 $this->FormManager = &$FormManager;
50 $this->Database = $FormManager->Database;
51 $this->Definition = array();
52 $this->Values = array();
53 $this->ValuesFilter = array();
54 $this->ValuesValidate = array();
55 $this->OnSubmit = '';
56 }
57
58 function LoadDefaults(): void
59 {
60 foreach ($this->Definition['Items'] as $Index => $Item)
61 {
62 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
63 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
64 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
65 {
66 if (!array_key_exists($Index, $this->Values))
67 {
68 if (isset($Item['Default'])) $this->Values[$Index] = $Item['Default'];
69 else $this->Values[$Index] = null;
70 }
71 }
72 }
73 }
74
75 function SetClass(string $Name): void
76 {
77 $this->Definition = &$this->FormManager->Classes[$Name];
78 $this->LoadDefaults();
79 }
80
81 function GetValue(string $Index, string $Event = 'OnView'): string
82 {
83 $Item = $this->Definition['Items'][$Index];
84 $UseType = $this->GetItemType($Item);
85
86 $Result = $this->FormManager->Type->ExecuteTypeEvent($UseType, $Event,
87 array('Value' => $this->Values[$Index], 'Name' => $Index,
88 'Type' => $Item['Type'], 'Values' => $this->Values,
89 'Filter' => $this->Values[$Index]));
90 if ($Result == null) return '';
91 return $Result;
92 }
93
94 function ShowViewForm(): string
95 {
96 $Table = array(
97 //'Header' => array('Položka', 'Hodnota'),
98 'Rows' => array(),
99 );
100 foreach ($this->Definition['Items'] as $Index => $Item)
101 if (!array_key_exists('Hidden', $Item) or ($Item['Hidden'] == false))
102 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
103 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
104 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
105 {
106 $UseType = $this->GetItemType($Item);
107 $Edit = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnView',
108 array('Value' => $this->Values[$Index], 'Name' => $Index,
109 'Type' => $Item['Type'], 'Values' => $this->Values,
110 'Filter' => $this->ValuesFilter[$Index]));
111 if (array_key_exists('Suffix', $Item)) $Edit .= ' '.$Item['Suffix'];
112 if (!$this->FormManager->Type->IsHidden($UseType))
113 array_push($Table['Rows'], array($Item['Caption'].':', $Edit));
114 }
115 $Output = '<fieldset><legend>'.$this->Definition['Title'].'</legend>'.Table($Table).
116 '</fieldset>';
117 return $Output;
118 }
119
120 function ShowEditForm(): string
121 {
122 if (!array_key_exists('SubmitText', $this->Definition)) $this->Definition['SubmitText'] = 'Uložit';
123 $Output = '<form enctype="multipart/form-data" class="Form" action="'.$this->OnSubmit.'" method="post">'.$this->ShowEditBlock().
124 '<div><input name="submit" type="submit" value="'.$this->Definition['SubmitText'].'" /> '.
125 '<input type="button" value="Zrušit" onclick="location.href=\'?\'"/></div></form>';
126 return $Output;
127 }
128
129 function ShowEditBlock(string $Context = ''): string
130 {
131 $Hidden = '';
132 $IsHidden = false;
133 $Table = array(
134 //'Header' => array('Položka', 'Hodnota'),
135 'Rows' => array(),
136 );
137 if ($Context != '') $Context = $Context.'-';
138 foreach ($this->Definition['Items'] as $Index => $Item)
139 {
140 if (!array_key_exists('ReadOnly', $Item)) $Item['ReadOnly'] = false;
141 if ($Item['ReadOnly'] == false)
142 if (!array_key_exists('Hidden', $Item) or ($Item['Hidden'] == false))
143 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
144 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
145 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
146 {
147 $Parameters = array('Value' => $this->Values[$Index], 'Name' => $Index,
148 'Type' => $Item['Type'], 'Values' => $this->Values);
149 if (array_key_exists('Null', $Item)) $Parameters['Null'] = $Item['Null'];
150 else unset($Parameters['Null']);
151 if (array_key_exists('OnPreset', $Item)) $Parameters['OnPreset'] = $Item['OnPreset'];
152 else unset($Parameters['OnPreset']);
153
154 $UseType = $this->GetItemType($Item);
155 $Edit = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnEdit', $Parameters);
156 if (array_key_exists('Suffix', $Item)) $Edit .= $Item['Suffix'];
157
158 $Caption = $Item['Caption'].':';
159 if (array_key_exists($Index, $this->ValuesValidate) and
160 $this->ValuesValidate[$Index])
161 {
162 $Format = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'GetValidationFormat', array());
163 if ($Format != '') $Caption .= '<br/><small>'.$Format.'</small>';
164 $Caption = '<span style="color:red;">'.$Caption.'</span>';
165 }
166 if (!$this->FormManager->Type->IsHidden($UseType))
167 array_push($Table['Rows'], array($Caption, $Edit));
168 else $Hidden .= $Edit;
169 }
170 }
171 $Output = '<fieldset><legend>'.$this->Definition['Title'].'</legend>'.Table($Table).
172 $Hidden.'</fieldset>';
173 return $Output;
174 }
175
176 function GetItemType($Item): string
177 {
178 if (array_key_exists($Item['Type'], $this->FormManager->FormTypes))
179 {
180 if (!array_key_exists($Item['Type'], $this->FormManager->Type->TypeDefinitionList))
181 $this->FormManager->Type->RegisterType($Item['Type'], '',
182 $this->FormManager->FormTypes[$Item['Type']]);
183 if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Reference')
184 $UseType = 'OneToMany';
185 else if ($this->FormManager->FormTypes[$Item['Type']]['Type'] == 'Enumeration')
186 $UseType = 'Enumeration';
187 } else $UseType = $Item['Type'];
188
189 return $UseType;
190 }
191
192 function LoadValuesFromDatabase(string $Id): void
193 {
194 foreach ($this->Definition['Items'] as $Index => $Item)
195 {
196 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
197 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
198 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
199 {
200 $UseType = $this->GetItemType($Item);
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 }
207 $Columns = implode(',', $Columns);
208 if (array_key_exists('SQL', $this->Definition))
209 $SourceTable = '('.$this->Definition['SQL'].') AS `TX`';
210 else $SourceTable = '`'.$this->Definition['Table'].'` AS `TX`';
211 $DbResult = $this->Database->query('SELECT '.$Columns.' FROM '.$SourceTable.' WHERE `TX`.`Id`='.$Id);
212 if ($DbResult->num_rows == 1)
213 {
214 $DbRow = $DbResult->fetch_array();
215 foreach ($this->Definition['Items'] as $Index => $Item)
216 {
217 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
218 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
219 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
220 {
221 $UseType = $this->GetItemType($Item);
222 $this->Values[$Index] = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnLoadDb',
223 array('Value' => $DbRow[$Index], 'Name' => $Index,
224 'Type' => $Item['Type'], 'Values' => $this->Values));
225 $this->ValuesFilter[$Index] = $DbRow[$Index.'_Filter'];
226 }
227 }
228 } else throw new Exception('Item '.$Id.' not found');
229 }
230
231 function SaveValuesToDatabase(string $Id)
232 {
233 $Values = array();
234 foreach ($this->Definition['Items'] as $Index => $Item)
235 {
236 if (array_key_exists($Index, $this->Values))
237 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
238 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
239 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
240 {
241 $Parameters = array('Value' => $this->Values[$Index], 'Name' => $Index,
242 'Type' => $Item['Type'], 'Values' => $this->Values);
243 $UseType = $this->GetItemType($Item);
244 $Values[$Index] = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnSaveDb', $Parameters);
245 if (($Item['Type'] == 'Password') and ($Values[$Index] == '')) unset($Values[$Index]);
246 }
247 }
248 if ($Id == 0)
249 {
250 $Values['Id'] = $Id;
251 $this->Database->insert($this->Definition['Table'], $Values);
252 } else
253 $this->Database->update($this->Definition['Table'], 'Id='.$Id, $Values);
254 }
255
256 function HasAllPostVariables(): bool
257 {
258 $Result = array_key_exists('submit', $_POST);
259
260 foreach ($this->Definition['Items'] as $Index => $Item)
261 {
262 if (!array_key_exists('ReadOnly', $Item)) $Item['ReadOnly'] = false;
263 if ($Item['ReadOnly'] == false)
264 if (!array_key_exists('Hidden', $Item) or ($Item['Hidden'] == false))
265 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
266 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
267 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
268 {
269 $UseType = $this->GetItemType($Item);
270 if (!$this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnCanLoad',
271 array('Value' => $this->Values[$Index], 'Name' => $Index,
272 'Type' => $Item['Type'], 'Values' => $this->Values,
273 'Filter' => $this->Values[$Index])))
274 {
275 $Result = false;
276 break;
277 }
278 }
279 }
280
281 return $Result;
282 }
283
284 function LoadValuesFromForm(): void
285 {
286 $this->Values = $this->LoadValuesFromFormBlock();
287 }
288
289 function LoadValuesFromFormBlock(string $Context = ''): array
290 {
291 if ($Context != '') $Context = $Context.'-';
292 $Values = array();
293 foreach ($this->Definition['Items'] as $Index => $Item)
294 {
295 if (!array_key_exists('Hidden', $Item) or ($Item['Hidden'] == false))
296 {
297 if ((!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
298 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
299 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne'))) and
300 (!array_key_exists('ReadOnly', $Item) or
301 (array_key_exists('ReadOnly', $Item) and
302 ($Item['ReadOnly'] != true))))
303 {
304 //if (array_key_exists($Context.$Index, $_POST))
305 $UseType = $this->GetItemType($Item);
306 $Parameters = array('Name' => $Index, 'Type' => $Item['Type'], 'Values' => $this->Values);
307 if (array_key_exists('Null', $Item)) $Parameters['Null'] = $Item['Null'];
308 else unset($Parameters['Null']);
309 $Values[$Index] = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnLoad',
310 $Parameters);
311 }
312 } else
313 {
314 if (isset($Item['Default']))
315 {
316 if (isset($Item['Null']) and ($Item['Null'] == true))
317 $Values[$Index] = null;
318 else $Values[$Index] = $Item['Default'];
319 }
320 }
321 }
322 return $Values;
323 }
324
325 // Check if filled value is in valid form
326 function Validate(): bool
327 {
328 $Valid = true;
329 foreach ($this->Definition['Items'] as $Index => $Item)
330 {
331 if ((!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
332 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
333 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne'))) and
334 (!array_key_exists('ReadOnly', $Item) or
335 (array_key_exists('ReadOnly', $Item) and
336 ($Item['ReadOnly'] != true))))
337 {
338 //if (array_key_exists($Context.$Index, $_POST))
339 $UseType = $this->GetItemType($Item);
340 $Parameters = array('Value' => $this->Values[$Index]);
341 if (array_key_exists('Null', $Item)) $Parameters['Null'] = $Item['Null'];
342 else $Parameters['Null'] = false;
343 if (!$this->FormManager->Type->ExecuteTypeEvent($UseType, 'Validate',
344 $Parameters))
345 {
346 $this->ValuesValidate[$Index] = true;
347 $Valid = false;
348 }
349 }
350 }
351 if ($Valid == false) throw new Exception('not validated');
352 return $Valid;
353 }
354}
355
356function MakeLink(string $Target, string $Title): string
357{
358 return '<a href="'.$Target.'">'.$Title.'</a>';
359}
360
361function Table(array $Table): string
362{
363 $Result = '<table class="BasicTable">';
364 if (array_key_exists('Header', $Table))
365 {
366 $Result .= '<tr>';
367 foreach ($Table['Header'] as $Item)
368 $Result .= '<th>'.$Item.'</th>';
369 $Result .= '</tr>';
370 }
371 foreach ($Table['Rows'] as $Row)
372 {
373 $Result .= '<tr>';
374 foreach ($Row as $Index => $Item)
375 {
376 if ($Index == 0) $Class = ' class="Header"'; else $Class = '';
377 $Result .= '<td'.$Class.' style="width: '.(floor(100 / count($Row))).'%">'.$Item.'</td>';
378 }
379 $Result .= '</tr>';
380 }
381 $Result .= '</table>';
382 return $Result;
383}
Note: See TracBrowser for help on using the repository browser.