]> git.mxchange.org Git - core.git/blob - inc/main/classes/helper/html/forms/class_HtmlFormHelper.php
7b6fc3aa92dbde32f85dbdd20130b93568a3097c
[core.git] / inc / main / classes / helper / html / forms / class_HtmlFormHelper.php
1 <?php
2 // Own namespace
3 namespace CoreFramework\Helper;
4
5 // Import framework stuff
6 use CoreFramework\Registry\Generic\Registry;
7 use CoreFramework\Template\CompileableTemplate;
8
9 /**
10  * A helper for constructing web forms
11  *
12  * @author              Roland Haeder <webmaster@shipsimu.org>
13  * @version             0.0.0
14  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team
15  * @license             GNU GPL 3.0 or any newer version
16  * @link                http://www.shipsimu.org
17  *
18  * This program is free software: you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation, either version 3 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program. If not, see <http://www.gnu.org/licenses/>.
30  */
31 class HtmlFormHelper extends BaseHtmlHelper implements HelpableTemplate {
32         /**
33          * Whether the form tag is opened (keep at FALSE or else your forms will
34          * never work!)
35          */
36         private $formOpened = FALSE;
37
38         /**
39          * Name of the form
40          */
41         private $formName = '';
42
43         /**
44          * Whether form tag is enabled (default: TRUE)
45          */
46         private $formEnabled = TRUE;
47
48         // Class Constants
49         const EXCEPTION_FORM_NAME_INVALID       = 0x120;
50         const EXCEPTION_CLOSED_FORM             = 0x121;
51         const EXCEPTION_OPENED_FORM             = 0x122;
52         const EXCEPTION_UNEXPECTED_CLOSED_GROUP = 0x123;
53
54         /**
55          * Protected constructor
56          *
57          * @return      void
58          */
59         protected function __construct () {
60                 // Call parent constructor
61                 parent::__construct(__CLASS__);
62         }
63
64         /**
65          * Creates the helper class with the given template engine instance and form name
66          *
67          * @param       $templateInstance       An instance of a valid template engine
68          * @param       $formName                       Name of the form
69          * @param       $formId                         Value for 'id' attribute (default: $formName)
70          * @param       $withForm                       Whether include the form tag
71          * @return      $helperInstance         A preparedf instance of this helper
72          */
73         public static final function createHtmlFormHelper (CompileableTemplate $templateInstance, $formName, $formId = FALSE, $withForm = TRUE) {
74                 // Get new instance
75                 $helperInstance = new HtmlFormHelper();
76
77                 // Set template instance
78                 $helperInstance->setTemplateInstance($templateInstance);
79
80                 // Is the form id not set?
81                 if ($formId === FALSE) {
82                         // Use form id from form name
83                         $formId = $formName;
84                 } // END - if
85
86                 // Set form name
87                 $helperInstance->setFormName($formName);
88
89                 // A form-less field may say 'FALSE' here...
90                 if ($withForm === TRUE) {
91                         // Create the form
92                         $helperInstance->addFormTag($formName, $formId);
93                 } else {
94                         // Disable form
95                         $helperInstance->enableForm(FALSE);
96                 }
97
98                 // Return the prepared instance
99                 return $helperInstance;
100         }
101
102         /**
103          * Add the form tag or close it an already opened form tag
104          *
105          * @param       $formName       Name of the form (default: FALSE)
106          * @param       $formId         Id of the form (attribute 'id'; default: FALSE)
107          * @return      void
108          * @throws      InvalidFormNameException        If the form name is invalid ( = FALSE)
109          * @todo        Add some unique PIN here to bypass problems with some browser and/or extensions
110          */
111         public function addFormTag ($formName = FALSE, $formId = FALSE) {
112                 // When the form is not yet opened at least form name must be valid
113                 if (($this->formOpened === FALSE) && ($formName === FALSE)) {
114                         // Thrown an exception
115                         throw new InvalidFormNameException ($this, self::EXCEPTION_FORM_NAME_INVALID);
116                 } // END - if
117
118                 // Close the form is default
119                 $formContent = '</form>';
120
121                 // Check whether we shall open or close the form
122                 if (($this->formOpened === FALSE) && ($this->formEnabled === TRUE)) {
123                         // Add HTML code
124                         $formContent = sprintf("<form name=\"%s\" class=\"forms\" action=\"%s/%s\" method=\"%s\" target=\"%s\"",
125                                 $formName,
126                                 $this->getConfigInstance()->getConfigEntry('base_url'),
127                                 $this->getConfigInstance()->getConfigEntry('form_action'),
128                                 $this->getConfigInstance()->getConfigEntry('form_method'),
129                                 $this->getConfigInstance()->getConfigEntry('form_target')
130                         );
131
132                         // Add form id as well
133                         $formContent .= sprintf(" id=\"%s_form\"",
134                                 $formId
135                         );
136
137                         // Add close bracket
138                         $formContent .= '>';
139
140                         // Open the form and remeber the form name
141                         $this->formOpened = TRUE;
142
143                         // Add it to the content
144                         $this->addHeaderContent($formContent);
145                 } else {
146                         // Add the hidden field required to identify safely this form
147                         $this->addInputHiddenField('form', $this->getFormName());
148
149                         // Is a group open?
150                         if ($this->ifGroupOpenedPreviously()) {
151                                 // Then automatically close it here
152                                 $this->addFormGroup();
153                         } // END - if
154
155                         // Simply close it
156                         $this->formOpened = FALSE;
157
158                         // Add it to the content
159                         $this->addFooterContent($formContent);
160                 }
161         }
162
163         /**
164          * Add a text input tag to the form or throw an exception if it is not yet
165          * opened. The field's name will be set as id.
166          *
167          * @param       $fieldName              Input field name
168          * @param       $fieldValue             Input default value (default: empty)
169          * @return      void
170          * @throws      FormClosedException             If the form is not yet opened
171          */
172         public function addInputTextField ($fieldName, $fieldValue = '') {
173                 // Is the form opened?
174                 if (($this->formOpened === FALSE) && ($this->formEnabled === TRUE)) {
175                         // Throw an exception
176                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
177                 } // END - if
178
179                 // Generate the content
180                 $inputContent = sprintf("<input type=\"text\" class=\"textfield %s_field\" name=\"%s\" value=\"%s\" />",
181                         $fieldName,
182                         $fieldName,
183                         $fieldValue
184                 );
185
186                 // And add it maybe with a 'li' tag
187                 $this->addContentToPreviousGroup($inputContent);
188         }
189
190         /**
191          * Add a text input tag to the form with pre-loaded default value
192          *
193          * @param       $fieldName      Input field name
194          * @return      void
195          */
196         public function addInputTextFieldWithDefault ($fieldName) {
197                 // Get the value from instance
198                 $fieldValue = $this->getValueField($fieldName);
199                 //* DEBUG: */ print __METHOD__.':'.$fieldName.'='.$fieldValue."<br />\n";
200
201                 // Add the text field
202                 $this->addInputTextField($fieldName, $fieldValue);
203         }
204
205         /**
206          * Add a password input tag to the form or throw an exception if it is not
207          * yet opened. The field's name will be set as id.
208          *
209          * @param       $fieldName              Input field name
210          * @param       $fieldValue             Input default value (default: empty)
211          * @return      void
212          * @throws      FormClosedException             If the form is not yet opened
213          */
214         public function addInputPasswordField ($fieldName, $fieldValue = '') {
215                 // Is the form opened?
216                 if (($this->formOpened === FALSE) && ($this->formEnabled === TRUE)) {
217                         // Throw an exception
218                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
219                 } // END - if
220
221                 // Generate the content
222                 $inputContent = sprintf("<input type=\"password\" class=\"password %s_field\" name=\"%s\" value=\"%s\" />",
223                         $fieldName,
224                         $fieldName,
225                         $fieldValue
226                 );
227
228                 // And add it
229                 $this->addContentToPreviousGroup($inputContent);
230         }
231
232         /**
233          * Add a hidden input tag to the form or throw an exception if it is not
234          * yet opened. The field's name will be set as id.
235          *
236          * @param       $fieldName              Input field name
237          * @param       $fieldValue             Input default value (default: empty)
238          * @return      void
239          * @throws      FormClosedException             If the form is not yet opened
240          */
241         public function addInputHiddenField ($fieldName, $fieldValue = '') {
242                 // Is the form opened?
243                 if (($this->formOpened === FALSE) && ($this->formEnabled === TRUE)) {
244                         // Throw an exception
245                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
246                 } // END - if
247
248                 // Generate the content
249                 $inputContent = sprintf("<input type=\"hidden\" name=\"%s\" value=\"%s\" />",
250                         $fieldName,
251                         $fieldValue
252                 );
253
254                 // And add it
255                 $this->addContentToPreviousGroup($inputContent);
256         }
257
258         /**
259          * Add a hidden input tag to the form with pre-loaded default value
260          *
261          * @param       $fieldName      Input field name
262          * @return      void
263          */
264         public function addInputHiddenFieldWithDefault ($fieldName) {
265                 // Get the value from instance
266                 $fieldValue = $this->getValueField($fieldName);
267                 //* DEBUG: */ print __METHOD__.':'.$fieldName.'='.$fieldValue."<br />\n";
268
269                 // Add the text field
270                 $this->addInputHiddenField($fieldName, $fieldValue);
271         }
272
273         /**
274          * Add a hidden input tag to the form with configuration value
275          *
276          * @param       $fieldName      Input field name
277          * @param       $prefix         Prefix for configuration without trailing _
278          * @return      void
279          */
280         public function addInputHiddenConfiguredField ($fieldName, $prefix) {
281                 // Get the value from instance
282                 $fieldValue = $this->getConfigInstance()->getConfigEntry("{$prefix}_{$fieldName}");
283                 //* DEBUG: */ print __METHOD__.':'.$fieldName.'='.$fieldValue."<br />\n";
284
285                 // Add the text field
286                 $this->addInputHiddenField($fieldName, $fieldValue);
287         }
288
289         /**
290          * Add a checkbox input tag to the form or throw an exception if it is not
291          * yet opened. The field's name will be set as id.
292          *
293          * @param       $fieldName              Input field name
294          * @param       $fieldChecked   Whether the field is checked (defaut: checked)
295          * @return      void
296          * @throws      FormClosedException             If the form is not yet opened
297          */
298         public function addInputCheckboxField ($fieldName, $fieldChecked = TRUE) {
299                 // Is the form opened?
300                 if (($this->formOpened === FALSE) && ($this->formEnabled === TRUE)) {
301                         // Throw an exception
302                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
303                 } // END - if
304
305                 // Set whether the check box is checked...
306                 $checked = " checked=\"checked\"";
307                 if ($fieldChecked === FALSE) $checked = ' ';
308
309                 // Generate the content
310                 $inputContent = sprintf("<input type=\"checkbox\" name=\"%s\" class=\"checkbox %s_field\" value=\"1\"%s/>",
311                         $fieldName,
312                         $fieldName,
313                         $checked
314                 );
315
316                 // And add it
317                 $this->addContentToPreviousGroup($inputContent);
318         }
319
320         /**
321          * Add a reset input tag to the form or throw an exception if it is not
322          * yet opened. The field's name will be set as id.
323          *
324          * @param       $buttonText             Text displayed on the button
325          * @return      void
326          * @throws      FormClosedException             If the form is not yet opened
327          */
328         public function addInputResetButton ($buttonText) {
329                 // Is the form opened?
330                 if (($this->formOpened === FALSE) && ($this->formEnabled === TRUE)) {
331                         // Throw an exception
332                         throw new FormClosedException (array($this, 'reset'), self::EXCEPTION_CLOSED_FORM);
333                 } // END - if
334
335                 // Generate the content
336                 $inputContent = sprintf("<input type=\"reset\" class=\"reset_button\" id=\"%s_reset\" value=\"%s\" />",
337                         $this->getFormName(),
338                         $buttonText
339                 );
340
341                 // And add it
342                 $this->addContentToPreviousGroup($inputContent);
343         }
344
345         /**
346          * Add a reset input tag to the form or throw an exception if it is not
347          * yet opened. The field's name will be set as id.
348          *
349          * @param       $buttonText             Text displayed on the button
350          * @return      void
351          * @throws      FormClosedException             If the form is not yet opened
352          */
353         public function addInputSubmitButton ($buttonText) {
354                 // Is the form opened?
355                 if (($this->formOpened === FALSE) && ($this->formEnabled === TRUE)) {
356                         // Throw an exception
357                         throw new FormClosedException (array($this, 'submit'), self::EXCEPTION_CLOSED_FORM);
358                 } // END - if
359
360                 // Generate the content
361                 $inputContent = sprintf("<input type=\"submit\" class=\"submit_button\" id=\"%s_submit\" name=\"%s_button\" value=\"%s\" />",
362                         $this->getFormName(),
363                         $this->getFormName(),
364                         $buttonText
365                 );
366
367                 // And add it
368                 $this->addContentToPreviousGroup($inputContent);
369         }
370
371         /**
372          * Add a form group or close an already opened and open a new one
373          *
374          * @param       $groupId        Name of the group or last opened if empty
375          * @param       $groupText      Text including HTML to show above this group
376          * @return      void
377          * @throws      FormClosedException             If no form has been opened before
378          * @throws      EmptyVariableException  If $groupId is not set
379          */
380         public function addFormGroup ($groupId = '', $groupText = '') {
381                 // Is a form opened?
382                 if (($this->formOpened === FALSE) && ($this->formEnabled === TRUE)) {
383                         // Throw exception here
384                         throw new FormClosedException(array($this, $groupId), self::EXCEPTION_CLOSED_FORM);
385                 } // END - if
386
387                 // At least the group name should be set
388                 if ((empty($groupId)) && ($this->ifGroupOpenedPreviously() === FALSE)) {
389                         // Throw exception here
390                         throw new EmptyVariableException(array($this, 'groupId'), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
391                 } elseif (empty($groupId)) {
392                         // Close the last opened
393                         $groupId = $this->getPreviousGroupId();
394                 }
395
396                 // Same group to open?
397                 if (($this->ifGroupOpenedPreviously() === FALSE) && ($groupId === $this->getPreviousGroupId())) {
398                         // Abort here silently
399                         return FALSE;
400                 } // END - if
401
402                 // Initialize content with closing div by default
403                 $content = "    </div>\n</div><!-- Group - CLOSE //-->";
404
405                 // Is this group opened?
406                 if ($this->ifGroupOpenedPreviously() === FALSE) {
407                         // Begin the div/span blocks
408                         $content = sprintf("<!-- Group %s - OPEN //-->
409 <div class=\"group_box\" id=\"%s_group_box\">
410         <span class=\"group_text\" id=\"%s_group_text\">
411                 %s
412         </span>
413         <div class=\"group_field\" id=\"%s_group_field\">",
414                                 $groupId,
415                                 $groupId,
416                                 $groupId,
417                                 $groupText,
418                                 $groupId
419                         );
420
421                         // Switch the state
422                         $this->openGroupByIdContent($groupId, $content, "div");
423                 } else {
424                         // Is a sub group opened?
425                         if ($this->ifSubGroupOpenedPreviously()) {
426                                 // Close it here
427                                 $this->addFormSubGroup();
428                         } // END - if
429
430                         // Get previous group id
431                         $prevGroupId = $this->getPreviousGroupId();
432
433                         // Switch the state
434                         $this->closePreviousGroupByContent($content);
435
436                         // All call it again if group name is not empty
437                         if ((!empty($groupId)) && ($groupId != $prevGroupId)) {
438                                 //* DEBUG: */ echo $groupId.'/'.$prevGroupId."<br />\n";
439                                 $this->addFormGroup($groupId, $groupText);
440                         } // END - if
441                 }
442         }
443
444         /**
445          * Add a form sub group or close an already opened and open a new one or
446          * throws an exception if no group has been opened before or if sub group
447          * name is empty.
448          *
449          * @param       $subGroupId             Name of the group or last opened if empty
450          * @param       $subGroupText   Text including HTML to show above this group
451          * @return      void
452          * @throws      FormFormClosedException         If no group has been opened before
453          * @throws      EmptyVariableException          If $subGroupId is not set
454          */
455         public function addFormSubGroup ($subGroupId = '', $subGroupText = '') {
456                 // Is a group opened?
457                 if ($this->ifGroupOpenedPreviously() === FALSE) {
458                         // Throw exception here
459                         throw new FormFormClosedException(array($this, $subGroupId), self::EXCEPTION_UNEXPECTED_CLOSED_GROUP);
460                 } // END - if
461
462                 // At least the sub group name should be set
463                 if ((empty($subGroupId)) && ($this->ifSubGroupOpenedPreviously() === FALSE)) {
464                         // Throw exception here
465                         throw new EmptyVariableException(array($this, 'subGroupId'), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
466                 } elseif (empty($subGroupId)) {
467                         // Close the last opened
468                         $subGroupId = $this->getPreviousSubGroupId();
469                 }
470
471                 // Same sub group to open?
472                 if (($this->ifSubGroupOpenedPreviously() === FALSE) && ($subGroupId == $this->getPreviousSubGroupId())) {
473                         // Abort here silently
474                         return FALSE;
475                 } // END - if
476
477                 // Initialize content with closing div by default
478                 $content = "    </div>\n</div><!-- Sub group- CLOSE //-->";
479
480                 // Is this group opened?
481                 if ($this->ifSubGroupOpenedPreviously() === FALSE) {
482                         // Begin the span block
483                         $content = sprintf("<!-- Sub group %s - OPEN //-->
484 <div class=\"subgroup_box\" id=\"%s_subgroup_box\">
485         <span class=\"subgroup_text\" id=\"%s_subgroup_text\">
486                 %s
487         </span>
488         <div class=\"subgroup_field\" id=\"%s_subgroup_field\">",
489                                 $subGroupId,
490                                 $subGroupId,
491                                 $subGroupId,
492                                 $subGroupText,
493                                 $subGroupId
494                         );
495
496                         // Switch the state and remeber the name
497                         $this->openSubGroupByIdContent($subGroupId, $content, "div");
498                 } else {
499                         // Get previous sub group id
500                         $prevSubGroupId = $this->getPreviousSubGroupId();
501
502                         // Switch the state
503                         $this->closePreviousSubGroupByContent($content);
504
505                         // All call it again if sub group name is not empty
506                         if ((!empty($subGroupId)) && ($subGroupId != $prevSubGroupId)) {
507                                 $this->addFormSubGroup($subGroupId, $subGroupText);
508                         } // END - if
509                 }
510         }
511
512         /**
513          * Add text surrounded by a span block when there is a group opened before
514          * or else by a div block.
515          *
516          * @param       $fieldName                      Field name
517          * @param       $fieldText                      Text for the field
518          * @return      void
519          * @throws      FormClosedException             If the form is not yet opened
520          */
521         public function addFieldText ($fieldName, $fieldText) {
522                 // Is the form opened?
523                 if (($this->formOpened === FALSE) && ($this->formEnabled === TRUE)) {
524                         // Throw an exception
525                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
526                 } // END - if
527
528                 // Set the block type
529                 $block = 'div';
530                 if ($this->ifGroupOpenedPreviously()) $block = 'span';
531
532                 // Generate the content
533                 $inputContent = sprintf("       <%s id=\"%s_text\">
534                 %s
535         </%s>",
536                         $block,
537                         $fieldName,
538                         $fieldText,
539                         $block
540                 );
541
542                 // And add it
543                 $this->addContentToPreviousGroup($inputContent);
544         }
545
546         /**
547          * Add text (notes) surrounded by a div block. Still opened groups or sub
548          * groups will be automatically closed.
549          *
550          * @param       $noteId         Id for this note
551          * @param       $formNotes      The form notes we shell addd
552          * @return      void
553          * @throws      FormClosedException             If the form is not yet opened
554          */
555         public function addFormNote ($noteId, $formNotes) {
556                 // Is the form opened?
557                 if (($this->formOpened === FALSE) && ($this->formEnabled === TRUE)) {
558                         // Throw an exception
559                         throw new FormClosedException (array($this, 'form_notes'), self::EXCEPTION_CLOSED_FORM);
560                 } // END - if
561
562                 // Generate the content
563                 $inputContent = sprintf("       <div id=\"form_note_%s\">
564                 %s
565         </div>",
566                         $noteId,
567                         $formNotes
568                 );
569
570                 // And add it
571                 $this->addContentToPreviousGroup($inputContent);
572         }
573
574         /**
575          * Adds a selection box as a sub group to the form. Do not box this into
576          * another sub group. Sub-sub groups are not (yet) supported.
577          *
578          * @param       $selectId               Id of the selection box
579          * @param       $firstEntry             Content to be added as first non-selectable entry
580          * @return      void
581          * @throws      FormClosedException             If the form is not yet opened
582          */
583         public function addInputSelectField ($selectId, $firstEntry) {
584                 // Is the form group opened?
585                 if (($this->formOpened === FALSE) && ($this->formEnabled === TRUE)) {
586                         // Throw an exception
587                         throw new FormClosedException (array($this, 'form_notes'), self::EXCEPTION_CLOSED_FORM);
588                 } // END - if
589
590                 // Shall we close or open the sub group?
591                 if (($this->ifSubGroupOpenedPreviously() === FALSE) && ($this->getPreviousSubGroupId() !== $selectId)) {
592                         // Initialize first entry (which might be non-selectable if content is provided
593                         if (!empty($firstEntry)) {
594                                 // Add selection around it
595                                 $firstEntry = sprintf("<option value=\"invalid\" disabled=\"disabled\">%s</option>\n",
596                                         $firstEntry
597                                 );
598                         } // END - if
599
600                         // Construct the opening select tag
601                         $content = sprintf("<select class=\"select_box\" id=\"%s_%s\" name=\"%s\">\n%s",
602                                 $this->getFormName(),
603                                 $selectId,
604                                 $selectId,
605                                 $firstEntry
606                         );
607
608                         // Open the sub group
609                         $this->openSubGroupByIdContent($selectId, $content, "select");
610                 } elseif ($this->getPreviousSubGroupId() != $selectId) {
611                         // Something went wrong!
612                         $this->debugInstance(__METHOD__."(): Previous sub group id {$this->getPreviousSubGroupId()} does not match current id {$selectId}.");
613                 } else {
614                         // Close the sub group
615                         $this->closePreviousSubGroupByContent("</select>");
616                 }
617         }
618
619         /**
620          * Adds a non-selectable sub option to a previously added selection box.
621          * This method does *not* validate if there is already a sub option added
622          * with the same name. We need to finish this here!
623          *
624          * @param       $subName        Name of the sub action
625          * @param       $subValue       Value of the sub action
626          * @return      void
627          * @throws      HelperNoPreviousOpenedSubGroupException If no previously opened sub group was found
628          * @todo        Add checking if sub option is already added
629          */
630         public function addSelectSubOption ($subName, $subValue) {
631                 // Is there a sub group (shall be a selection box!)
632                 if ($this->ifSubGroupOpenedPreviously() === FALSE) {
633                         // Then throw an exception here
634                         throw new HelperNoPreviousOpenedSubGroupException(array($this, $content), self::EXCEPTION_NO_PREVIOUS_SUB_GROUP_OPENED);
635                 } // END - if
636
637                 // Render the content
638                 $content = sprintf("<option value=\"invalid\" class=\"suboption suboption_%s\" disabled=\"disabled\">%s</option>\n",
639                         $subName,
640                         $subValue
641                 );
642
643                 // Add the content to the previously opened sub group
644                 $this->addContentToPreviousGroup($content);
645         }
646
647         /**
648          * Adds a selectable option to a previously added selection box. This method
649          * does *not* validate if there is already a sub option added with the same
650          * name. We need to finish this here!
651          *
652          * @param       $optionName     Name of the sub action
653          * @param       $optionValue    Value of the sub action
654          * @return      void
655          * @throws      HelperNoPreviousOpenedSubGroupException If no previously opened sub group was found
656          * @todo        Add checking if sub option is already added
657          */
658         public function addSelectOption ($optionName, $optionValue) {
659                 // Is there a sub group (shall be a selection box!)
660                 if ($this->ifSubGroupOpenedPreviously() === FALSE) {
661                         // Then throw an exception here
662                         throw new HelperNoPreviousOpenedSubGroupException(array($this, $content), self::EXCEPTION_NO_PREVIOUS_SUB_GROUP_OPENED);
663                 } // END - if
664
665                 // Render the content
666                 $content = sprintf("<option value=\"%s\" class=\"option option_%s\">%s</option>\n",
667                         $optionName,
668                         $optionName,
669                         $optionValue
670                 );
671
672                 // Add the content to the previously opened sub group
673                 $this->addContentToPreviousGroup($content);
674         }
675
676         /**
677          * Adds a pre-configured CAPTCHA
678          *
679          * @return      void
680          */
681         public function addCaptcha () {
682                 // Init instance
683                 $extraInstance = NULL;
684
685                 try {
686                         // Get last executed pre filter
687                         $extraInstance = Registry::getRegistry()->getInstance('extra');
688                 } catch (NullPointerException $e) {
689                         // Instance in registry is not set (NULL)
690                         // @TODO We need to log this later
691                 }
692
693                 // Get a configured instance
694                 $captchaInstance = ObjectFactory::createObjectByConfiguredName($this->getFormName() . '_captcha_class', array($this, $extraInstance));
695
696                 // Initiate the CAPTCHA
697                 $captchaInstance->initiateCaptcha();
698
699                 // Render the CAPTCHA code
700                 $captchaInstance->renderCode();
701
702                 // Get the content and add it to the helper
703                 $this->addContentToPreviousGroup($captchaInstance->renderContent());
704         }
705
706         /**
707          * Enables/disables the form tag usage
708          *
709          * @param       $formEnabled    Whether form is enabled or disabled
710          * @return      void
711          */
712         public final function enableForm ($formEnabled = TRUE) {
713                 $this->formEnabled = (bool) $formEnabled;
714         }
715
716         /**
717          * Setter for form name
718          *
719          * @param       $formName       Name of this form
720          * @return      void
721          */
722         public final function setFormName ($formName) {
723                 $this->formName = (string) $formName;
724         }
725
726         /**
727          * Getter for form name
728          *
729          * @return      $formName       Name of this form
730          */
731         public final function getFormName () {
732                 return $this->formName;
733         }
734
735         /**
736          * Checks whether the registration requires a valid email address
737          *
738          * @return      $required       Whether the email address is required
739          */
740         public function ifRegisterRequiresEmailVerification () {
741                 $required = ($this->getConfigInstance()->getConfigEntry('register_requires_email') == 'Y');
742                 return $required;
743         }
744
745         /**
746          * Checks whether profile data shall be asked
747          *
748          * @return      $required       Whether profile data shall be asked
749          */
750         public function ifRegisterIncludesProfile () {
751                 $required = ($this->getConfigInstance()->getConfigEntry('register_includes_profile') == 'Y');
752                 return $required;
753         }
754
755         /**
756          * Checks whether this form is secured by a CAPTCHA
757          *
758          * @return      $isSecured      Whether this form is secured by a CAPTCHA
759          */
760         public function ifFormSecuredWithCaptcha () {
761                 $isSecured = ($this->getConfigInstance()->getConfigEntry($this->getFormName() . '_captcha_secured') == 'Y');
762                 return $isSecured;
763         }
764
765         /**
766          * Checks whether personal data shall be asked
767          *
768          * @return      $required       Whether personal data shall be asked
769          */
770         public function ifRegisterIncludesPersonaData () {
771                 $required = ($this->getConfigInstance()->getConfigEntry('register_personal_data') == 'Y');
772                 return $required;
773         }
774
775         /**
776          * Checks whether for birthday shall be asked
777          *
778          * @return      $required       Whether birthday shall be asked
779          */
780         public function ifProfileIncludesBirthDay () {
781                 $required = ($this->getConfigInstance()->getConfigEntry('profile_includes_birthday') == 'Y');
782                 return $required;
783         }
784
785         /**
786          * Checks whether email addresses can only be once used
787          *
788          * @return      $isUnique
789          */
790         public function ifEmailMustBeUnique () {
791                 $isUnique = ($this->getConfigInstance()->getConfigEntry('register_email_unique') == 'Y');
792                 return $isUnique;
793         }
794
795         /**
796          * Checks whether the specified chat protocol is enabled in this form
797          *
798          * @return      $required       Whether the specified chat protocol is enabled
799          */
800         public function ifChatEnabled ($chatProtocol) {
801                 $required = ($this->getConfigInstance()->getConfigEntry('chat_enabled_' . $chatProtocol) == 'Y');
802                 return $required;
803         }
804
805         /**
806          * Checks whether login is enabled or disabled
807          *
808          * @return      $isEnabled      Whether the login is enabled or disabled
809          */
810         public function ifLoginIsEnabled () {
811                 $isEnabled = ($this->getConfigInstance()->getConfigEntry('login_enabled') == 'Y');
812                 return $isEnabled;
813         }
814
815         /**
816          * Checks whether login shall be done by username
817          *
818          * @return      $isEnabled      Whether the login shall be done by username
819          */
820         public function ifLoginWithUsername () {
821                 $isEnabled = ($this->getConfigInstance()->getConfigEntry('login_type') == "username");
822                 return $isEnabled;
823         }
824
825         /**
826          * Checks whether login shall be done by email
827          *
828          * @return      $isEnabled      Whether the login shall be done by email
829          */
830         public function ifLoginWithEmail () {
831                 $isEnabled = ($this->getConfigInstance()->getConfigEntry('login_type') == "email");
832                 return $isEnabled;
833         }
834
835         /**
836          * Checks whether guest login is allowed
837          *
838          * @return      $isAllowed      Whether guest login is allowed
839          */
840         public function ifGuestLoginAllowed () {
841                 $isAllowed = ($this->getConfigInstance()->getConfigEntry('guest_login_allowed') == 'Y');
842                 return $isAllowed;
843         }
844
845         /**
846          * Checks whether the email address change must be confirmed
847          *
848          * @return      $requireConfirm         Whether email change must be confirmed
849          */
850         public function ifEmailChangeRequireConfirmation () {
851                 $requireConfirm = ($this->getConfigInstance()->getConfigEntry('email_change_confirmation') == 'Y');
852                 return $requireConfirm;
853         }
854
855         /**
856          * Checks whether the rules has been updated
857          *
858          * @return      $rulesUpdated   Whether rules has been updated
859          * @todo        Implement check if rules have been changed
860          */
861         public function ifRulesHaveChanged () {
862                 return FALSE;
863         }
864
865         /**
866          * Checks whether email change is allowed
867          *
868          * @return      $emailChange    Whether changing email address is allowed
869          */
870         public function ifEmailChangeAllowed () {
871                 $emailChange = ($this->getConfigInstance()->getConfigEntry('email_change_allowed') == 'Y');
872                 return $emailChange;
873         }
874
875         /**
876          * Checks whether the user account is unconfirmed
877          *
878          * @return      $isUnconfirmed  Whether the user account is unconfirmed
879          */
880         public function ifUserAccountUnconfirmed () {
881                 $isUnconfirmed = ($this->getValueField(UserDatabaseWrapper::DB_COLUMN_USER_STATUS) === $this->getConfigInstance()->getConfigEntry('user_status_unconfirmed'));
882                 return $isUnconfirmed;
883         }
884
885         /**
886          * Checks whether the user account is locked
887          *
888          * @return      $isUnconfirmed  Whether the user account is locked
889          */
890         public function ifUserAccountLocked () {
891                 $isUnconfirmed = ($this->getValueField(UserDatabaseWrapper::DB_COLUMN_USER_STATUS) === $this->getConfigInstance()->getConfigEntry('user_status_locked'));
892                 return $isUnconfirmed;
893         }
894
895         /**
896          * Checks whether the user account is a guest
897          *
898          * @return      $isUnconfirmed  Whether the user account is a guest
899          */
900         public function ifUserAccountGuest () {
901                 $isUnconfirmed = ($this->getValueField(UserDatabaseWrapper::DB_COLUMN_USER_STATUS) === $this->getConfigInstance()->getConfigEntry('user_status_guest'));
902                 return $isUnconfirmed;
903         }
904
905         /**
906          * Checks whether the refill page is active which should be not the default
907          * on non-web applications.
908          *
909          * @return      $refillActive   Whether the refill page is active
910          */
911         public function ifRefillPageActive () {
912                 $refillActive = ($this->getConfigInstance()->getConfigEntry('refill_page_active') == 'Y');
913                 return $refillActive;
914         }
915
916         /**
917          * Flushs the content out (not yet secured against open forms, etc.!) or
918          * close the form automatically
919          *
920          * @return      void
921          * @throws      FormOpenedException             If the form is still open
922          */
923         public function flushContent () {
924                 // Is the form still open?
925                 if (($this->formOpened === TRUE) && ($this->formEnabled === TRUE)) {
926                         // Close the form automatically
927                         $this->addFormTag();
928                 } elseif ($this->formEnabled === FALSE) {
929                         if ($this->ifSubGroupOpenedPreviously()) {
930                                 // Close sub group
931                                 $this->addFormSubGroup();
932                         } elseif ($this->ifGroupOpenedPreviously()) {
933                                 // Close group
934                                 $this->addFormGroup();
935                         }
936                 }
937
938                 // Send content to template engine
939                 //* DEBUG: */ print __METHOD__.": form=".$this->getFormName().", size=".strlen($this->renderContent())."<br />\n";
940                 $this->getTemplateInstance()->assignVariable($this->getFormName(), $this->renderContent());
941         }
942
943 }