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