source: trunk/Common/Form/Form.php

Last change on this file was 948, checked in by chronos, 21 months ago
  • Fixed: IP address database field size in News table for IPv6.
File size: 13.9 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 $DbRow = $DbResult->fetch_array();
213 foreach ($this->Definition['Items'] as $Index => $Item)
214 {
215 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
216 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
217 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
218 {
219 $UseType = $this->GetItemType($Item);
220 $this->Values[$Index] = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnLoadDb',
221 array('Value' => $DbRow[$Index], 'Name' => $Index,
222 'Type' => $Item['Type'], 'Values' => $this->Values));
223 $this->ValuesFilter[$Index] = $DbRow[$Index.'_Filter'];
224 }
225 }
226 }
227
228 function SaveValuesToDatabase(string $Id)
229 {
230 $Values = array();
231 foreach ($this->Definition['Items'] as $Index => $Item)
232 {
233 if (array_key_exists($Index, $this->Values))
234 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
235 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
236 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
237 {
238 $Parameters = array('Value' => $this->Values[$Index], 'Name' => $Index,
239 'Type' => $Item['Type'], 'Values' => $this->Values);
240 $UseType = $this->GetItemType($Item);
241 $Values[$Index] = $this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnSaveDb', $Parameters);
242 if (($Item['Type'] == 'Password') and ($Values[$Index] == '')) unset($Values[$Index]);
243 }
244 }
245 if ($Id == 0)
246 {
247 $Values['Id'] = $Id;
248 $this->Database->insert($this->Definition['Table'], $Values);
249 } else
250 $this->Database->update($this->Definition['Table'], 'Id='.$Id, $Values);
251 }
252
253 function HasAllPostVariables(): bool
254 {
255 $Result = array_key_exists('submit', $_POST);
256
257 foreach ($this->Definition['Items'] as $Index => $Item)
258 {
259 if (!array_key_exists('ReadOnly', $Item)) $Item['ReadOnly'] = false;
260 if ($Item['ReadOnly'] == false)
261 if (!array_key_exists('Hidden', $Item) or ($Item['Hidden'] == false))
262 if (!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
263 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
264 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne')))
265 {
266 $UseType = $this->GetItemType($Item);
267 if (!$this->FormManager->Type->ExecuteTypeEvent($UseType, 'OnCanLoad',
268 array('Value' => $this->Values[$Index], 'Name' => $Index,
269 'Type' => $Item['Type'], 'Values' => $this->Values,
270 'Filter' => $this->Values[$Index])))
271 {
272 $Result = false;
273 break;
274 }
275 }
276 }
277
278 return $Result;
279 }
280
281 function LoadValuesFromForm(): void
282 {
283 $this->Values = $this->LoadValuesFromFormBlock();
284 }
285
286 function LoadValuesFromFormBlock(string $Context = ''): array
287 {
288 if ($Context != '') $Context = $Context.'-';
289 $Values = array();
290 foreach ($this->Definition['Items'] as $Index => $Item)
291 {
292 if (!array_key_exists('Hidden', $Item) or ($Item['Hidden'] == false))
293 {
294 if ((!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
295 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
296 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne'))) and
297 (!array_key_exists('ReadOnly', $Item) or
298 (array_key_exists('ReadOnly', $Item) and
299 ($Item['ReadOnly'] != true))))
300 {
301 //if (array_key_exists($Context.$Index, $_POST))
302 $UseType = $this->GetItemType($Item);
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 {
313 if (isset($Item['Null']) and ($Item['Null'] == true))
314 $Values[$Index] = null;
315 else $Values[$Index] = $Item['Default'];
316 }
317 }
318 }
319 return $Values;
320 }
321
322 // Check if filled value is in valid form
323 function Validate(): bool
324 {
325 $Valid = true;
326 foreach ($this->Definition['Items'] as $Index => $Item)
327 {
328 if ((!array_key_exists($Item['Type'], $this->FormManager->FormTypes) or
329 (array_key_exists($Item['Type'], $this->FormManager->FormTypes) and
330 ($this->FormManager->FormTypes[$Item['Type']]['Type'] != 'ManyToOne'))) and
331 (!array_key_exists('ReadOnly', $Item) or
332 (array_key_exists('ReadOnly', $Item) and
333 ($Item['ReadOnly'] != true))))
334 {
335 //if (array_key_exists($Context.$Index, $_POST))
336 $UseType = $this->GetItemType($Item);
337 $Parameters = array('Value' => $this->Values[$Index]);
338 if (array_key_exists('Null', $Item)) $Parameters['Null'] = $Item['Null'];
339 else $Parameters['Null'] = false;
340 if (!$this->FormManager->Type->ExecuteTypeEvent($UseType, 'Validate',
341 $Parameters))
342 {
343 $this->ValuesValidate[$Index] = true;
344 $Valid = false;
345 }
346 }
347 }
348 if ($Valid == false) throw new Exception('not validated');
349 return $Valid;
350 }
351}
352
353function MakeLink(string $Target, string $Title): string
354{
355 return '<a href="'.$Target.'">'.$Title.'</a>';
356}
357
358function Table(array $Table): string
359{
360 $Result = '<table class="BasicTable">';
361 if (array_key_exists('Header', $Table))
362 {
363 $Result .= '<tr>';
364 foreach ($Table['Header'] as $Item)
365 $Result .= '<th>'.$Item.'</th>';
366 $Result .= '</tr>';
367 }
368 foreach ($Table['Rows'] as $Row)
369 {
370 $Result .= '<tr>';
371 foreach ($Row as $Index => $Item)
372 {
373 if ($Index == 0) $Class = ' class="Header"'; else $Class = '';
374 $Result .= '<td'.$Class.' style="width: '.(floor(100 / count($Row))).'%">'.$Item.'</td>';
375 }
376 $Result .= '</tr>';
377 }
378 $Result .= '</table>';
379 return $Result;
380}
Note: See TracBrowser for help on using the repository browser.