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