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