fb0f1b24d39d2784c6629e09dd06cb1648816d75
[shipsimu.git] / inc / classes / main / helper / web / class_WebFormHelper.php
1 <?php
2 /**
3  * A helper for constructing web forms
4  *
5  * @author              Roland Haeder <webmaster@ship-simu.org>
6  * @version             0.0.0
7  * @copyright   Copyright(c) 2007, 2008 Roland Haeder, this is free software
8  * @license             GNU GPL 3.0 or any newer version
9  * @link                http://www.ship-simu.org
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <http://www.gnu.org/licenses/>.
23  */
24 class WebFormHelper extends BaseHelper {
25         /**
26          * Wether the form tag is opened (keep at false or else your forms will
27          * never work!)
28          */
29         private $formOpened = false;
30
31         /**
32          * Name of the form
33          */
34         private $formName = "";
35
36         /**
37          * Wether the group is opened or not
38          */
39         private $groupOpened = false;
40
41         /**
42          * Wether the sub group is opened or not
43          */
44         private $subGroupOpened = false;
45
46         /**
47          * Name of the sub group
48          */
49         private $subGroupName = "";
50
51         // Class Constants
52         const EXCEPTION_FORM_NAME_INVALID       = 0xb00;
53         const EXCEPTION_CLOSED_FORM             = 0xb01;
54         const EXCEPTION_OPENED_FORM             = 0xb02;
55         const EXCEPTION_UNEXPECTED_CLOSED_GROUP = 0xb03;
56
57         /**
58          * Private constructor
59          *
60          * @return      void
61          */
62         protected function __construct () {
63                 // Call parent constructor
64                 parent::__construct(__CLASS__);
65
66                 // Set part description
67                 $this->setObjectDescription("Helper class for HTML forms");
68
69                 // Create unique ID number
70                 $this->createUniqueID();
71         }
72
73         /**
74          * Creates the helper class with the given template engine instance and form name
75          *
76          * @param       $templateInstance       An instance of a valid template engine
77          * @param       $formName                       Name of the form
78          * @param       $formId                         Value for "id" attribute (default: $formName)
79          * @return      $helperInstance         A preparedf instance of this class
80          */
81         public final static function createWebFormHelper (CompileableTemplate $templateInstance, $formName, $formId = false) {
82                 // Get new instance
83                 $helperInstance = new WebFormHelper();
84
85                 // Set template instance
86                 $helperInstance->setTemplateInstance($templateInstance);
87
88                 // Is the form id not set?
89                 if ($formId === false) {
90                         // Use form id from form name
91                         $formId = $formName;
92                 }
93
94                 // Create the form
95                 $helperInstance->addFormTag($formName, $formId);
96
97                 // Return the prepared instance
98                 return $helperInstance;
99         }
100
101         /**
102          * Add the form tag or close it an already opened form tag
103          *
104          * @param       $formName       Name of the form (default: false)
105          * @param       $formId         Id of the form (attribute "id"; default: false)
106          * @return      void
107          * @throws      InvalidFormNameException        If the form name is invalid (=false)
108          */
109         public function addFormTag ($formName = false, $formId = false) {
110                 // When the form is not yet opened at least form name must be valid
111                 if (($this->formOpened === false) && ($formName === false)) {
112                         // Thrown an exception
113                         throw new InvalidFormNameException ($this, self::EXCEPTION_FORM_NAME_INVALID);
114                 }
115
116                 // Close the form is default
117                 $formContent = "</form>";
118
119                 // Check wether we shall open or close the form
120                 if ($this->formOpened === false) {
121                         // Add HTML code
122                         $formContent = sprintf("<form name=\"%s\" class=\"forms\" action=\"%s\" method=\"%s\" target=\"%s\"",
123                                 $formName,
124                                 $this->getConfigInstance()->readConfig('form_action'),
125                                 $this->getConfigInstance()->readConfig('form_method'),
126                                 $this->getConfigInstance()->readConfig('form_target')
127                         );
128
129                         // Is the form id set?
130                         if ($formId !== false) {
131                                 // Then add it as well
132                                 $formContent .= sprintf(" id=\"%s_form\"",
133                                         $formId
134                                 );
135                         }
136
137                         // Add close bracket
138                         $formContent .= ">";
139
140                         // Open the form and remeber the form name
141                         $this->formOpened = true;
142                         $this->formName = $formName;
143                 } else {
144                         // Add the hidden field required to identify safely this form
145                         $this->addInputHiddenField('form', $this->formName);
146
147                         // Is a group open?
148                         if ($this->groupOpened === true) {
149                                 // Then automatically close it here
150                                 $this->addFormGroup("", "");
151                         }
152
153                         // @TODO Add some unique PIN here to bypass problems with some browser and/or extensions
154                         // Simply close it
155                         $this->formOpened = false;
156                 }
157
158                 // Add it to the content
159                 $this->addContent($formContent);
160         }
161
162         /**
163          * Add a text input tag to the form or throw an exception if it is not yet
164          * opened. The field's name will be set as id.
165          *
166          * @param       $fieldName                      Input field name
167          * @param       $fieldValue                     Input default value (default: empty)
168          * @return      void
169          * @throws      FormClosedException             If the form is not yet opened
170          */
171         public function addInputTextField ($fieldName, $fieldValue = "") {
172                 // Is the form opened?
173                 if ($this->formOpened === false) {
174                         // Throw an exception
175                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
176                 }
177
178                 // Generate the content
179                 $inputContent = sprintf("<input type=\"text\" class=\"textfield\" id=\"%s\" name=\"%s\" value=\"%s\" />",
180                         $fieldName,
181                         $fieldName,
182                         $fieldValue
183                 );
184
185                 // And add it maybe with a "li" tag
186                 $this->addContent($inputContent);
187         }
188
189         /**
190          * Add a password input tag to the form or throw an exception if it is not
191          * yet opened. The field's name will be set as id.
192          *
193          * @param       $fieldName                      Input field name
194          * @param       $fieldValue                     Input default value (default: empty)
195          * @return      void
196          * @throws      FormClosedException             If the form is not yet opened
197          */
198         public function addInputPasswordField ($fieldName, $fieldValue = "") {
199                 // Is the form opened?
200                 if ($this->formOpened === false) {
201                         // Throw an exception
202                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
203                 }
204
205                 // Generate the content
206                 $inputContent = sprintf("<input type=\"password\" class=\"password\" id=\"%s\" name=\"%s\" value=\"%s\" />",
207                         $fieldName,
208                         $fieldName,
209                         $fieldValue
210                 );
211
212                 // And add it
213                 $this->addContent($inputContent);
214         }
215
216         /**
217          * Add a hidden input tag to the form or throw an exception if it is not
218          * yet opened. The field's name will be set as id.
219          *
220          * @param       $fieldName                      Input field name
221          * @param       $fieldValue                     Input default value (default: empty)
222          * @return      void
223          * @throws      FormClosedException             If the form is not yet opened
224          */
225         public function addInputHiddenField ($fieldName, $fieldValue = "") {
226                 // Is the form opened?
227                 if ($this->formOpened === false) {
228                         // Throw an exception
229                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
230                 }
231
232                 // Generate the content
233                 $inputContent = sprintf("<input type=\"hidden\" name=\"%s\" value=\"%s\" />",
234                         $fieldName,
235                         $fieldValue
236                 );
237
238                 // And add it
239                 $this->addContent($inputContent);
240         }
241
242         /**
243          * Add a checkbox input tag to the form or throw an exception if it is not
244          * yet opened. The field's name will be set as id.
245          *
246          * @param       $fieldName                      Input field name
247          * @param       $fieldChecked           Wether the field is checked (defaut: checked)
248          * @return      void
249          * @throws      FormClosedException             If the form is not yet opened
250          */
251         public function addInputCheckboxField ($fieldName, $fieldChecked = true) {
252                 // Is the form opened?
253                 if ($this->formOpened === false) {
254                         // Throw an exception
255                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
256                 }
257
258                 // Set wether the check box is checked...
259                 $checked = " checked=\"checked\"";
260                 if ($fieldChecked === false) $checked = " ";
261
262                 // Generate the content
263                 $inputContent = sprintf("<input type=\"checkbox\" name=\"%s\" class=\"checkbox\" id=\"%s\" value=\"1\"%s/>",
264                         $fieldName,
265                         $fieldName,
266                         $checked
267                 );
268
269                 // And add it
270                 $this->addContent($inputContent);
271         }
272
273         /**
274          * Add a reset input tag to the form or throw an exception if it is not
275          * yet opened. The field's name will be set as id.
276          *
277          * @param       $buttonText             Text displayed on the button
278          * @return      void
279          * @throws      FormClosedException             If the form is not yet opened
280          */
281         public function addInputResetButton ($buttonText) {
282                 // Is the form opened?
283                 if ($this->formOpened === false) {
284                         // Throw an exception
285                         throw new FormClosedException (array($this, "reset"), self::EXCEPTION_CLOSED_FORM);
286                 }
287
288                 // Generate the content
289                 $inputContent = sprintf("<input type=\"reset\" class=\"reset_button\" id=\"%s_reset\" value=\"%s\" />",
290                         $this->formName,
291                         $buttonText
292                 );
293
294                 // And add it
295                 $this->addContent($inputContent);
296         }
297
298         /**
299          * Add a reset input tag to the form or throw an exception if it is not
300          * yet opened. The field's name will be set as id.
301          *
302          * @param       $buttonText                     Text displayed on the button
303          * @return      void
304          * @throws      FormClosedException             If the form is not yet opened
305          */
306         public function addInputSubmitButton ($buttonText) {
307                 // Is the form opened?
308                 if ($this->formOpened === false) {
309                         // Throw an exception
310                         throw new FormClosedException (array($this, "submit"), self::EXCEPTION_CLOSED_FORM);
311                 }
312
313                 // Generate the content
314                 $inputContent = sprintf("<input type=\"submit\" class=\"submit_button\" id=\"%s_submit\" name=\"%s_button\" value=\"%s\" />",
315                         $this->formName,
316                         $this->formName,
317                         $buttonText
318                 );
319
320                 // And add it
321                 $this->addContent($inputContent);
322         }
323
324         /**
325          * Add a form group or close an already opened and open a new one
326          *
327          * @param       $groupName      Name of the group
328          * @param       $groupText      Text including HTML to show above this group
329          * @return      void
330          * @throws      FormClosedException             If no form has been opened before
331          * @throws      EmptyVariableException  If $groupName is not set
332          */
333         public function addFormGroup ($groupName, $groupText) {
334                 // Is a form opened?
335                 if ($this->formOpened === false) {
336                         // Throw exception here
337                         throw new FormClosedException(array($this, $groupName), self::EXCEPTION_CLOSED_FORM);
338                 }
339
340                 // At least the group name should be set
341                 if ((empty($groupName)) && ($this->groupOpened === false)) {
342                         // Throw exception here
343                         throw new EmptyVariableException(array($this, 'groupName'), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
344                 }
345
346                 // Initialize content with closing div by default
347                 $content = "    </div>\n</div><!-- Group - CLOSE //-->";
348
349                 // Is this group opened?
350                 if ($this->groupOpened === false) {
351                         // Begin the div/span blocks
352                         $content = sprintf("<!-- Group %s - OPEN //-->
353 <div class=\"group_box\" id=\"%s_group_box\">
354         <span class=\"group_text\" id=\"%s_group_text\">
355                 %s
356         </span>
357         <div class=\"group_field\" id=\"%s_group_field\">",
358                                 $groupName,
359                                 $groupName,
360                                 $groupName,
361                                 $groupText,
362                                 $groupName
363                         );
364
365                         // Add the content
366                         $this->addContent($content);
367
368                         // Switch the state
369                         $this->groupOpened = true;
370                 } else {
371                         // Is a sub group opened?
372                         if ($this->subGroupOpened === true) {
373                                 // Close it here
374                                 $this->addFormSubGroup("", "");
375                         }
376
377                         // Add the content
378                         $this->addContent($content);
379
380                         // Switch the state
381                         $this->groupOpened = false;
382
383                         // All call it again if the group name is not empty
384                         if (!empty($groupName)) {
385                                 $this->addFormGroup($groupName, $groupText);
386                         }
387                 }
388         }
389
390         /**
391          * Add a form sub group or close an already opened and open a new one or
392          * throws an exception if no group has been opened before or if the sub
393          * group name is empty.
394          *
395          * @param       $subGroupName   Name of the group
396          * @param       $subGroupText   Text including HTML to show above this group
397          * @return      void
398          * @throws      FormGroupClosedException        If no group has been opened before
399          * @throws      EmptyVariableException          If $subGroupName is not set
400          */
401         public function addFormSubGroup ($subGroupName, $subGroupText) {
402                 // Is a group opened?
403                 if ($this->groupOpened === false) {
404                         // Throw exception here
405                         throw new FormGroupClosedException(array($this, $subGroupName), self::EXCEPTION_UNEXPECTED_CLOSED_GROUP);
406                 }
407
408                 // At least the sub group name should be set
409                 if ((empty($subGroupName)) && ($this->subGroupOpened === false)) {
410                         // Throw exception here
411                         throw new EmptyVariableException(array($this, 'groupName'), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
412                 }
413
414                 // Initialize content with closing div by default
415                 $content = "    </div>\n</div><!-- Sub group- CLOSE //-->";
416
417                 // Is this group opened?
418                 if ($this->subGroupOpened === false) {
419                         // Begin the span block
420                         $content = sprintf("<!-- Sub group %s - OPEN //-->
421 <div class=\"subgroup_box\" id=\"%s_subgroup_box\">
422         <span class=\"subgroup_text\" id=\"%s_subgroup_text\">
423                 %s
424         </span>
425         <div class=\"subgroup_field\" id=\"%s_subgroup_field\">",
426                                 $subGroupName,
427                                 $subGroupName,
428                                 $subGroupName,
429                                 $subGroupText,
430                                 $subGroupName
431                         );
432
433                         // Add the content
434                         $this->addContent($content);
435
436                         // Switch the state and remeber the name
437                         $this->subGroupOpened = true;
438                         $this->subGroupName = $subGroupName;
439                 } else {
440                         // Add the content
441                         $this->addContent($content);
442
443                         // Switch the state
444                         $this->subGroupOpened = false;
445
446                         // All call it again if sub group name is not empty
447                         if (!empty($subGroupName)) {
448                                 $this->addFormSubGroup($subGroupName, $subGroupText);
449                         }
450                 }
451         }
452
453         /**
454          * Add text surrounded by a span block when there is a group opened before
455          * or else by a div block.
456          *
457          * @param       $fieldName                      Field name
458          * @param       $fieldText                      Text for the field
459          * @return      void
460          * @throws      FormClosedException             If the form is not yet opened
461          */
462         public function addFieldText ($fieldName, $fieldText) {
463                 // Is the form opened?
464                 if ($this->formOpened === false) {
465                         // Throw an exception
466                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
467                 }
468
469                 // Set the block type
470                 $block = "div";
471                 if ($this->groupOpened === true) $block = "span";
472
473                 // Generate the content
474                 $inputContent = sprintf("       <%s id=\"%s_text\">
475                 %s
476         </%s>",
477                         $block,
478                         $fieldName,
479                         $fieldText,
480                         $block
481                 );
482
483                 // And add it
484                 $this->addContent($inputContent);
485         }
486
487         /**
488          * Add text (notes) surrounded by a div block. Still opened groups or sub
489          * groups will be automatically closed.
490          *
491          * @param       $formNotes      The form notes we shell addd
492          * @return      void
493          * @throws      FormClosedException             If the form is not yet opened
494          */
495         public function addFormNote ($formNotes) {
496                 // Is the form opened?
497                 if ($this->formOpened === false) {
498                         // Throw an exception
499                         throw new FormClosedException (array($this, "form_notes"), self::EXCEPTION_CLOSED_FORM);
500                 }
501
502                 // Is a group open?
503                 if ($this->groupOpened === true) {
504                         // Then automatically close it here
505                         $this->addFormGroup("unknown", "");
506                 }
507
508                 // Generate the content
509                 $inputContent = sprintf("       <div id=\"form_note\">
510                 %s
511         </div>",
512                         $formNotes
513                 );
514
515                 // And add it
516                 $this->addContent($inputContent);
517         }
518
519         /**
520          * Checks wether the registration requires a valid email address
521          *
522          * @return      $required       Wether the email address is required
523          */
524         public function ifRegisterRequiresEmailVerification () {
525                 $required = ($this->getConfigInstance()->readConfig('register_requires_email') == "Y");
526                 return $required;
527         }
528
529         /**
530          * Checks wether profile data shall be asked
531          *
532          * @return      $required       Wether profile shall be asked
533          */
534         public function ifRegisterIncludesProfile () {
535                 $required = ($this->getConfigInstance()->readConfig('register_includes_profile') == "Y");
536                 return $required;
537         }
538
539         /**
540          * Checks wether personal data shall be asked
541          *
542          * @return      $required       Wether personal data shall be asked
543          */
544         public function ifRegisterIncludesPersonaData () {
545                 $required = ($this->getConfigInstance()->readConfig('register_personal_data') == "Y");
546                 return $required;
547         }
548
549         /**
550          * Checks wether email addresses can only be once used
551          *
552          * @return      $isUnique
553          */
554         public function ifEmailMustBeUnique () {
555                 $isUnique = ($this->getConfigInstance()->readConfig('register_email_unique') == "Y");
556                 return $isUnique;
557         }
558
559         /**
560          * Checks wether the specified chat protocol is enabled in this form
561          *
562          * @return      $required       Wether the specified chat protocol is enabled
563          */
564         public function ifChatEnabled ($chatProtocol) {
565                 $required = ($this->getConfigInstance()->readConfig(sprintf("chat_enabled_%s", $chatProtocol)) == "Y");
566                 return $required;
567         }
568
569         /**
570          * Flushs the content out (not yet secured against open forms, etc.!) or
571          * throw an exception if it is not yet closed
572          *
573          * @return      void
574          * @throws      FormOpenedException             If the form is still open
575          */
576         public function flushContent () {
577                 // Is the form still open?
578                 if ($this->formOpened === true) {
579                         // Throw an exception
580                         throw new FormOpenedException ($this, self::EXCEPTION_OPENED_FORM);
581                 }
582
583                 // Send content to template engine
584                 $this->getTemplateInstance()->assignVariable($this->formName, $this->getContent());
585         }
586 }
587
588 // [EOF]
589 ?>