6dbffb5c01a33ed1c02b32856b2140420e875b68
[shipsimu.git] / inc / classes / main / helper / web / class_WebFormHelper.php
1 <?php
2 /**
3  * A helper for constructing web forms
4  *
5  * @author              Roland Haeder <webmaster@ship-simu.org>
6  * @version             0.0.0
7  * @copyright   Copyright(c) 2007, 2008 Roland Haeder, this is free software
8  * @license             GNU GPL 3.0 or any newer version
9  * @link                http://www.ship-simu.org
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <http://www.gnu.org/licenses/>.
23  */
24 class WebFormHelper extends BaseHelper {
25         /**
26          * Wether the form tag is opened (keep at false or else your forms will
27          * never work!)
28          */
29         private $formOpened = false;
30
31         /**
32          * Name of the form
33          */
34         private $formName = "";
35
36         /**
37          * Wether the group is opened or not
38          */
39         private $groupOpened = false;
40
41         /**
42          * Wether the sub group is opened or not
43          */
44         private $subGroupOpened = false;
45
46         /**
47          * Name of the sub group
48          */
49         private $subGroupName = "";
50
51         // Class Constants
52         const EXCEPTION_FORM_NAME_INVALID       = 0x030;
53         const EXCEPTION_CLOSED_FORM             = 0x031;
54         const EXCEPTION_OPENED_FORM             = 0x032;
55         const EXCEPTION_UNEXPECTED_CLOSED_GROUP = 0x033;
56
57         /**
58          * Protected constructor
59          *
60          * @return      void
61          */
62         protected function __construct () {
63                 // Call parent constructor
64                 parent::__construct(__CLASS__);
65
66                 // Set part description
67                 $this->setObjectDescription("Helper class for HTML forms");
68
69                 // Create unique ID number
70                 $this->generateUniqueId();
71         }
72
73         /**
74          * Creates the helper class with the given template engine instance and form name
75          *
76          * @param       $templateInstance       An instance of a valid template engine
77          * @param       $formName                       Name of the form
78          * @param       $formId                         Value for "id" attribute (default: $formName)
79          * @return      $helperInstance         A preparedf instance of this class
80          */
81         public final static function createWebFormHelper (CompileableTemplate $templateInstance, $formName, $formId = false) {
82                 // Get new instance
83                 $helperInstance = new WebFormHelper();
84
85                 // Set template instance
86                 $helperInstance->setTemplateInstance($templateInstance);
87
88                 // Is the form id not set?
89                 if ($formId === false) {
90                         // Use form id from form name
91                         $formId = $formName;
92                 }
93
94                 // Create the form
95                 $helperInstance->addFormTag($formName, $formId);
96
97                 // Return the prepared instance
98                 return $helperInstance;
99         }
100
101         /**
102          * Add the form tag or close it an already opened form tag
103          *
104          * @param       $formName       Name of the form (default: false)
105          * @param       $formId         Id of the form (attribute "id"; default: false)
106          * @return      void
107          * @throws      InvalidFormNameException        If the form name is invalid (=false)
108          */
109         public function addFormTag ($formName = false, $formId = false) {
110                 // When the form is not yet opened at least form name must be valid
111                 if (($this->formOpened === false) && ($formName === false)) {
112                         // Thrown an exception
113                         throw new InvalidFormNameException ($this, self::EXCEPTION_FORM_NAME_INVALID);
114                 }
115
116                 // Close the form is default
117                 $formContent = "</form>";
118
119                 // Check wether we shall open or close the form
120                 if ($this->formOpened === false) {
121                         // Add HTML code
122                         $formContent = sprintf("<form name=\"%s\" class=\"forms\" action=\"%s/%s\" method=\"%s\" target=\"%s\"",
123                                 $formName,
124                                 $this->getConfigInstance()->readConfig('base_url'),
125                                 $this->getConfigInstance()->readConfig('form_action'),
126                                 $this->getConfigInstance()->readConfig('form_method'),
127                                 $this->getConfigInstance()->readConfig('form_target')
128                         );
129
130                         // Is the form id set?
131                         if ($formId !== false) {
132                                 // Then add it as well
133                                 $formContent .= sprintf(" id=\"%s_form\"",
134                                         $formId
135                                 );
136                         }
137
138                         // Add close bracket
139                         $formContent .= ">";
140
141                         // Open the form and remeber the form name
142                         $this->formOpened = true;
143                         $this->formName = $formName;
144                 } else {
145                         // Add the hidden field required to identify safely this form
146                         $this->addInputHiddenField('form', $this->formName);
147
148                         // Is a group open?
149                         if ($this->groupOpened === true) {
150                                 // Then automatically close it here
151                                 $this->addFormGroup("", "");
152                         }
153
154                         // @TODO Add some unique PIN here to bypass problems with some browser and/or extensions
155                         // Simply close it
156                         $this->formOpened = false;
157                 }
158
159                 // Add it to the content
160                 $this->addContent($formContent);
161         }
162
163         /**
164          * Add a text input tag to the form or throw an exception if it is not yet
165          * opened. The field's name will be set as id.
166          *
167          * @param       $fieldName                      Input field name
168          * @param       $fieldValue                     Input default value (default: empty)
169          * @return      void
170          * @throws      FormClosedException             If the form is not yet opened
171          */
172         public function addInputTextField ($fieldName, $fieldValue = "") {
173                 // Is the form opened?
174                 if ($this->formOpened === false) {
175                         // Throw an exception
176                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
177                 }
178
179                 // Generate the content
180                 $inputContent = sprintf("<input type=\"text\" class=\"textfield\" id=\"%s\" name=\"%s\" value=\"%s\" />",
181                         $fieldName,
182                         $fieldName,
183                         $fieldValue
184                 );
185
186                 // And add it maybe with a "li" tag
187                 $this->addContent($inputContent);
188         }
189
190         /**
191          * Add a password input tag to the form or throw an exception if it is not
192          * yet opened. The field's name will be set as id.
193          *
194          * @param       $fieldName                      Input field name
195          * @param       $fieldValue                     Input default value (default: empty)
196          * @return      void
197          * @throws      FormClosedException             If the form is not yet opened
198          */
199         public function addInputPasswordField ($fieldName, $fieldValue = "") {
200                 // Is the form opened?
201                 if ($this->formOpened === false) {
202                         // Throw an exception
203                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
204                 }
205
206                 // Generate the content
207                 $inputContent = sprintf("<input type=\"password\" class=\"password\" id=\"%s\" name=\"%s\" value=\"%s\" />",
208                         $fieldName,
209                         $fieldName,
210                         $fieldValue
211                 );
212
213                 // And add it
214                 $this->addContent($inputContent);
215         }
216
217         /**
218          * Add a hidden input tag to the form or throw an exception if it is not
219          * yet opened. The field's name will be set as id.
220          *
221          * @param       $fieldName                      Input field name
222          * @param       $fieldValue                     Input default value (default: empty)
223          * @return      void
224          * @throws      FormClosedException             If the form is not yet opened
225          */
226         public function addInputHiddenField ($fieldName, $fieldValue = "") {
227                 // Is the form opened?
228                 if ($this->formOpened === false) {
229                         // Throw an exception
230                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
231                 }
232
233                 // Generate the content
234                 $inputContent = sprintf("<input type=\"hidden\" name=\"%s\" value=\"%s\" />",
235                         $fieldName,
236                         $fieldValue
237                 );
238
239                 // And add it
240                 $this->addContent($inputContent);
241         }
242
243         /**
244          * Add a checkbox 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       $fieldChecked           Wether the field is checked (defaut: checked)
249          * @return      void
250          * @throws      FormClosedException             If the form is not yet opened
251          */
252         public function addInputCheckboxField ($fieldName, $fieldChecked = true) {
253                 // Is the form opened?
254                 if ($this->formOpened === false) {
255                         // Throw an exception
256                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
257                 }
258
259                 // Set wether the check box is checked...
260                 $checked = " checked=\"checked\"";
261                 if ($fieldChecked === false) $checked = " ";
262
263                 // Generate the content
264                 $inputContent = sprintf("<input type=\"checkbox\" name=\"%s\" class=\"checkbox\" id=\"%s\" value=\"1\"%s/>",
265                         $fieldName,
266                         $fieldName,
267                         $checked
268                 );
269
270                 // And add it
271                 $this->addContent($inputContent);
272         }
273
274         /**
275          * Add a reset input tag to the form or throw an exception if it is not
276          * yet opened. The field's name will be set as id.
277          *
278          * @param       $buttonText             Text displayed on the button
279          * @return      void
280          * @throws      FormClosedException             If the form is not yet opened
281          */
282         public function addInputResetButton ($buttonText) {
283                 // Is the form opened?
284                 if ($this->formOpened === false) {
285                         // Throw an exception
286                         throw new FormClosedException (array($this, "reset"), self::EXCEPTION_CLOSED_FORM);
287                 }
288
289                 // Generate the content
290                 $inputContent = sprintf("<input type=\"reset\" class=\"reset_button\" id=\"%s_reset\" value=\"%s\" />",
291                         $this->formName,
292                         $buttonText
293                 );
294
295                 // And add it
296                 $this->addContent($inputContent);
297         }
298
299         /**
300          * Add a reset input tag to the form or throw an exception if it is not
301          * yet opened. The field's name will be set as id.
302          *
303          * @param       $buttonText                     Text displayed on the button
304          * @return      void
305          * @throws      FormClosedException             If the form is not yet opened
306          */
307         public function addInputSubmitButton ($buttonText) {
308                 // Is the form opened?
309                 if ($this->formOpened === false) {
310                         // Throw an exception
311                         throw new FormClosedException (array($this, "submit"), self::EXCEPTION_CLOSED_FORM);
312                 }
313
314                 // Generate the content
315                 $inputContent = sprintf("<input type=\"submit\" class=\"submit_button\" id=\"%s_submit\" name=\"%s_button\" value=\"%s\" />",
316                         $this->formName,
317                         $this->formName,
318                         $buttonText
319                 );
320
321                 // And add it
322                 $this->addContent($inputContent);
323         }
324
325         /**
326          * Add a form group or close an already opened and open a new one
327          *
328          * @param       $groupName      Name of the group
329          * @param       $groupText      Text including HTML to show above this group
330          * @return      void
331          * @throws      FormClosedException             If no form has been opened before
332          * @throws      EmptyVariableException  If $groupName is not set
333          */
334         public function addFormGroup ($groupName, $groupText) {
335                 // Is a form opened?
336                 if ($this->formOpened === false) {
337                         // Throw exception here
338                         throw new FormClosedException(array($this, $groupName), self::EXCEPTION_CLOSED_FORM);
339                 }
340
341                 // At least the group name should be set
342                 if ((empty($groupName)) && ($this->groupOpened === false)) {
343                         // Throw exception here
344                         throw new EmptyVariableException(array($this, 'groupName'), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
345                 }
346
347                 // Initialize content with closing div by default
348                 $content = "    </div>\n</div><!-- Group - CLOSE //-->";
349
350                 // Is this group opened?
351                 if ($this->groupOpened === false) {
352                         // Begin the div/span blocks
353                         $content = sprintf("<!-- Group %s - OPEN //-->
354 <div class=\"group_box\" id=\"%s_group_box\">
355         <span class=\"group_text\" id=\"%s_group_text\">
356                 %s
357         </span>
358         <div class=\"group_field\" id=\"%s_group_field\">",
359                                 $groupName,
360                                 $groupName,
361                                 $groupName,
362                                 $groupText,
363                                 $groupName
364                         );
365
366                         // Add the content
367                         $this->addContent($content);
368
369                         // Switch the state
370                         $this->groupOpened = true;
371                 } else {
372                         // Is a sub group opened?
373                         if ($this->subGroupOpened === true) {
374                                 // Close it here
375                                 $this->addFormSubGroup("", "");
376                         }
377
378                         // Add the content
379                         $this->addContent($content);
380
381                         // Switch the state
382                         $this->groupOpened = false;
383
384                         // All call it again if the group name is not empty
385                         if (!empty($groupName)) {
386                                 $this->addFormGroup($groupName, $groupText);
387                         }
388                 }
389         }
390
391         /**
392          * Add a form sub group or close an already opened and open a new one or
393          * throws an exception if no group has been opened before or if the sub
394          * group name is empty.
395          *
396          * @param       $subGroupName   Name of the group
397          * @param       $subGroupText   Text including HTML to show above this group
398          * @return      void
399          * @throws      FormGroupClosedException        If no group has been opened before
400          * @throws      EmptyVariableException          If $subGroupName is not set
401          */
402         public function addFormSubGroup ($subGroupName, $subGroupText) {
403                 // Is a group opened?
404                 if ($this->groupOpened === false) {
405                         // Throw exception here
406                         throw new FormGroupClosedException(array($this, $subGroupName), self::EXCEPTION_UNEXPECTED_CLOSED_GROUP);
407                 }
408
409                 // At least the sub group name should be set
410                 if ((empty($subGroupName)) && ($this->subGroupOpened === false)) {
411                         // Throw exception here
412                         throw new EmptyVariableException(array($this, 'groupName'), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
413                 }
414
415                 // Initialize content with closing div by default
416                 $content = "    </div>\n</div><!-- Sub group- CLOSE //-->";
417
418                 // Is this group opened?
419                 if ($this->subGroupOpened === false) {
420                         // Begin the span block
421                         $content = sprintf("<!-- Sub group %s - OPEN //-->
422 <div class=\"subgroup_box\" id=\"%s_subgroup_box\">
423         <span class=\"subgroup_text\" id=\"%s_subgroup_text\">
424                 %s
425         </span>
426         <div class=\"subgroup_field\" id=\"%s_subgroup_field\">",
427                                 $subGroupName,
428                                 $subGroupName,
429                                 $subGroupName,
430                                 $subGroupText,
431                                 $subGroupName
432                         );
433
434                         // Add the content
435                         $this->addContent($content);
436
437                         // Switch the state and remeber the name
438                         $this->subGroupOpened = true;
439                         $this->subGroupName = $subGroupName;
440                 } else {
441                         // Add the content
442                         $this->addContent($content);
443
444                         // Switch the state
445                         $this->subGroupOpened = false;
446
447                         // All call it again if sub group name is not empty
448                         if (!empty($subGroupName)) {
449                                 $this->addFormSubGroup($subGroupName, $subGroupText);
450                         }
451                 }
452         }
453
454         /**
455          * Add text surrounded by a span block when there is a group opened before
456          * or else by a div block.
457          *
458          * @param       $fieldName                      Field name
459          * @param       $fieldText                      Text for the field
460          * @return      void
461          * @throws      FormClosedException             If the form is not yet opened
462          */
463         public function addFieldText ($fieldName, $fieldText) {
464                 // Is the form opened?
465                 if ($this->formOpened === false) {
466                         // Throw an exception
467                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
468                 }
469
470                 // Set the block type
471                 $block = "div";
472                 if ($this->groupOpened === true) $block = "span";
473
474                 // Generate the content
475                 $inputContent = sprintf("       <%s id=\"%s_text\">
476                 %s
477         </%s>",
478                         $block,
479                         $fieldName,
480                         $fieldText,
481                         $block
482                 );
483
484                 // And add it
485                 $this->addContent($inputContent);
486         }
487
488         /**
489          * Add text (notes) surrounded by a div block. Still opened groups or sub
490          * groups will be automatically closed.
491          *
492          * @param       $formNotes      The form notes we shell addd
493          * @return      void
494          * @throws      FormClosedException             If the form is not yet opened
495          */
496         public function addFormNote ($formNotes) {
497                 // Is the form opened?
498                 if ($this->formOpened === false) {
499                         // Throw an exception
500                         throw new FormClosedException (array($this, "form_notes"), self::EXCEPTION_CLOSED_FORM);
501                 }
502
503                 // Is a group open?
504                 if ($this->groupOpened === true) {
505                         // Then automatically close it here
506                         $this->addFormGroup("", "");
507                 }
508
509                 // Generate the content
510                 $inputContent = sprintf("       <div id=\"form_note\">
511                 %s
512         </div>",
513                         $formNotes
514                 );
515
516                 // And add it
517                 $this->addContent($inputContent);
518         }
519
520         /**
521          * Checks wether the registration requires a valid email address
522          *
523          * @return      $required       Wether the email address is required
524          */
525         public function ifRegisterRequiresEmailVerification () {
526                 $required = ($this->getConfigInstance()->readConfig('register_requires_email') == "Y");
527                 return $required;
528         }
529
530         /**
531          * Checks wether profile data shall be asked
532          *
533          * @return      $required       Wether profile shall be asked
534          */
535         public function ifRegisterIncludesProfile () {
536                 $required = ($this->getConfigInstance()->readConfig('register_includes_profile') == "Y");
537                 return $required;
538         }
539
540         /**
541          * Checks wether personal data shall be asked
542          *
543          * @return      $required       Wether personal data shall be asked
544          */
545         public function ifRegisterIncludesPersonaData () {
546                 $required = ($this->getConfigInstance()->readConfig('register_personal_data') == "Y");
547                 return $required;
548         }
549
550         /**
551          * Checks wether email addresses can only be once used
552          *
553          * @return      $isUnique
554          */
555         public function ifEmailMustBeUnique () {
556                 $isUnique = ($this->getConfigInstance()->readConfig('register_email_unique') == "Y");
557                 return $isUnique;
558         }
559
560         /**
561          * Checks wether the specified chat protocol is enabled in this form
562          *
563          * @return      $required       Wether the specified chat protocol is enabled
564          */
565         public function ifChatEnabled ($chatProtocol) {
566                 $required = ($this->getConfigInstance()->readConfig(sprintf("chat_enabled_%s", $chatProtocol)) == "Y");
567                 return $required;
568         }
569
570         /**
571          * Checks wether login is enabled or disabled
572          *
573          * @return      $isEnabled      Wether the login is enabled or disabled
574          */
575         public function ifLoginIsEnabled () {
576                 $isEnabled = ($this->getConfigInstance()->readConfig('login_enabled') == "Y");
577                 return $isEnabled;
578         }
579
580         /**
581          * Checks wether login shall be done by username
582          *
583          * @return      $isEnabled      Wether the login shall be done by username
584          */
585         public function ifLoginWithUsername () {
586                 $isEnabled = ($this->getConfigInstance()->readConfig('login_type') == "username");
587                 return $isEnabled;
588         }
589
590         /**
591          * Checks wether login shall be done by email
592          *
593          * @return      $isEnabled      Wether the login shall be done by email
594          */
595         public function ifLoginWithEmail () {
596                 $isEnabled = ($this->getConfigInstance()->readConfig('login_type') == "email");
597                 return $isEnabled;
598         }
599
600         /**
601          * Checks wether guest login is allowed
602          *
603          * @return      $isAllowed      Wether guest login is allowed
604          */
605         public function ifGuestLoginAllowed () {
606                 $isAllowed = ($this->getConfigInstance()->readConfig('guest_login_allowed') == "Y");
607                 return $isAllowed;
608         }
609
610         /**
611          * Flushs the content out (not yet secured against open forms, etc.!) or
612          * throw an exception if it is not yet closed
613          *
614          * @return      void
615          * @throws      FormOpenedException             If the form is still open
616          */
617         public function flushContent () {
618                 // Is the form still open?
619                 if ($this->formOpened === true) {
620                         // Throw an exception
621                         throw new FormOpenedException ($this, self::EXCEPTION_OPENED_FORM);
622                 }
623
624                 // Send content to template engine
625                 $this->getTemplateInstance()->assignVariable($this->formName, $this->getContent());
626         }
627 }
628
629 // [EOF]
630 ?>