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