More style convensions applied, interface updated
[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       = 0xb00;
53         const EXCEPTION_CLOSED_FORM             = 0xb01;
54         const EXCEPTION_OPENED_FORM             = 0xb02;
55         const EXCEPTION_UNEXPECTED_CLOSED_GROUP = 0xb03;
56
57         /**
58          * Private 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("HTML-Formularhilfsklasse");
68         }
69
70         /**
71          * Creates the helper class with the given template engine instance and form name
72          *
73          * @param       $templateInstance       An instance of a valid template engine
74          * @param       $formName                       Name of the form
75          * @param       $formId                         Value for "id" attribute (default: $formName)
76          * @return      $helperInstance         A preparedf instance of this class
77          */
78         public final static function createWebFormHelper (CompileableTemplate $templateInstance, $formName, $formId = false) {
79                 // Get new instance
80                 $helperInstance = new WebFormHelper();
81
82                 // Set template instance
83                 $helperInstance->setTemplateInstance($templateInstance);
84
85                 // Is the form id not set?
86                 if ($formId === false) {
87                         // Use form id from form name
88                         $formId = $formName;
89                 }
90
91                 // Create the form
92                 $helperInstance->addFormTag($formName, $formId);
93
94                 // Return the prepared instance
95                 return $helperInstance;
96         }
97
98         /**
99          * Add the form tag or close it an already opened form tag
100          *
101          * @param       $formName       Name of the form (default: false)
102          * @param       $formId         Id of the form (attribute "id"; default: false)
103          * @return      void
104          * @throws      InvalidFormNameException        If the form name is invalid (=false)
105          */
106         public function addFormTag ($formName = false, $formId = false) {
107                 // When the form is not yet opened at least form name must be valid
108                 if (($this->formOpened === false) && ($formName === false)) {
109                         // Thrown an exception
110                         throw new InvalidFormNameException ($this, self::EXCEPTION_FORM_NAME_INVALID);
111                 }
112
113                 // Close the form is default
114                 $formContent = "</form>";
115
116                 // Check wether we shall open or close the form
117                 if ($this->formOpened === false) {
118                         // Add HTML code
119                         $formContent = sprintf("<form name=\"%s\" class=\"forms\" action=\"%s\" method=\"%s\" target=\"%s\"",
120                                 $formName,
121                                 $this->getConfigInstance()->readConfig('form_action'),
122                                 $this->getConfigInstance()->readConfig('form_method'),
123                                 $this->getConfigInstance()->readConfig('form_target')
124                         );
125
126                         // Is the form id set?
127                         if ($formId !== false) {
128                                 // Then add it as well
129                                 $formContent .= sprintf(" id=\"%s_form\"",
130                                         $formId
131                                 );
132                         }
133
134                         // Add close bracket
135                         $formContent .= ">";
136
137                         // Open the form and remeber the form name
138                         $this->formOpened = true;
139                         $this->formName = $formName;
140                 } else {
141                         // Add the hidden field required to identify safely this form
142                         $this->addInputHiddenField('form', $this->formName);
143
144                         // Is a group open?
145                         if ($this->groupOpened === true) {
146                                 // Then automatically close it here
147                                 $this->addFormGroup("", "");
148                         }
149
150                         // @TODO Add some unique PIN here to bypass problems with some browser and/or extensions
151                         // Simply close it
152                         $this->formOpened = false;
153                 }
154
155                 // Add it to the content
156                 $this->addContent($formContent);
157         }
158
159         /**
160          * Add a text input tag to the form or throw an exception if it is not yet
161          * opened. The field's name will be set as id.
162          *
163          * @param       $fieldName                      Input field name
164          * @param       $fieldValue                     Input default value (default: empty)
165          * @return      void
166          * @throws      FormClosedException             If the form is not yet opened
167          */
168         public function addInputTextField ($fieldName, $fieldValue = "") {
169                 // Is the form opened?
170                 if ($this->formOpened === false) {
171                         // Throw an exception
172                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
173                 }
174
175                 // Generate the content
176                 $inputContent = sprintf("<input type=\"text\" class=\"textfield\" id=\"%s\" name=\"%s\" value=\"%s\" />",
177                         $fieldName,
178                         $fieldName,
179                         $fieldValue
180                 );
181
182                 // And add it maybe with a "li" tag
183                 $this->addContent($inputContent);
184         }
185
186         /**
187          * Add a password input tag to the form or throw an exception if it is not
188          * yet opened. The field's name will be set as id.
189          *
190          * @param       $fieldName                      Input field name
191          * @param       $fieldValue                     Input default value (default: empty)
192          * @return      void
193          * @throws      FormClosedException             If the form is not yet opened
194          */
195         public function addInputPasswordField ($fieldName, $fieldValue = "") {
196                 // Is the form opened?
197                 if ($this->formOpened === false) {
198                         // Throw an exception
199                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
200                 }
201
202                 // Generate the content
203                 $inputContent = sprintf("<input type=\"password\" class=\"password\" id=\"%s\" name=\"%s\" value=\"%s\" />",
204                         $fieldName,
205                         $fieldName,
206                         $fieldValue
207                 );
208
209                 // And add it
210                 $this->addContent($inputContent);
211         }
212
213         /**
214          * Add a hidden input tag to the form or throw an exception if it is not
215          * yet opened. The field's name will be set as id.
216          *
217          * @param       $fieldName                      Input field name
218          * @param       $fieldValue                     Input default value (default: empty)
219          * @return      void
220          * @throws      FormClosedException             If the form is not yet opened
221          */
222         public function addInputHiddenField ($fieldName, $fieldValue = "") {
223                 // Is the form opened?
224                 if ($this->formOpened === false) {
225                         // Throw an exception
226                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
227                 }
228
229                 // Generate the content
230                 $inputContent = sprintf("<input type=\"hidden\" name=\"%s\" value=\"%s\" />",
231                         $fieldName,
232                         $fieldValue
233                 );
234
235                 // And add it
236                 $this->addContent($inputContent);
237         }
238
239         /**
240          * Add a checkbox input tag to the form or throw an exception if it is not
241          * yet opened. The field's name will be set as id.
242          *
243          * @param       $fieldName                      Input field name
244          * @param       $fieldChecked           Wether the field is checked (defaut: checked)
245          * @return      void
246          * @throws      FormClosedException             If the form is not yet opened
247          */
248         public function addInputCheckboxField ($fieldName, $fieldChecked = true) {
249                 // Is the form opened?
250                 if ($this->formOpened === false) {
251                         // Throw an exception
252                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
253                 }
254
255                 // Set wether the check box is checked...
256                 $checked = " checked=\"checked\"";
257                 if ($fieldChecked === false) $checked = " ";
258
259                 // Generate the content
260                 $inputContent = sprintf("<input type=\"checkbox\" name=\"%s\" class=\"checkbox\" id=\"%s\" value=\"1\"%s/>",
261                         $fieldName,
262                         $fieldName,
263                         $checked
264                 );
265
266                 // And add it
267                 $this->addContent($inputContent);
268         }
269
270         /**
271          * Add a reset input tag to the form or throw an exception if it is not
272          * yet opened. The field's name will be set as id.
273          *
274          * @param       $buttonText             Text displayed on the button
275          * @return      void
276          * @throws      FormClosedException             If the form is not yet opened
277          */
278         public function addInputResetButton ($buttonText) {
279                 // Is the form opened?
280                 if ($this->formOpened === false) {
281                         // Throw an exception
282                         throw new FormClosedException (array($this, "reset"), self::EXCEPTION_CLOSED_FORM);
283                 }
284
285                 // Generate the content
286                 $inputContent = sprintf("<input type=\"reset\" class=\"reset_button\" id=\"%s_reset\" value=\"%s\" />",
287                         $this->formName,
288                         $buttonText
289                 );
290
291                 // And add it
292                 $this->addContent($inputContent);
293         }
294
295         /**
296          * Add a reset input tag to the form or throw an exception if it is not
297          * yet opened. The field's name will be set as id.
298          *
299          * @param       $buttonText                     Text displayed on the button
300          * @return      void
301          * @throws      FormClosedException             If the form is not yet opened
302          */
303         public function addInputSubmitButton ($buttonText) {
304                 // Is the form opened?
305                 if ($this->formOpened === false) {
306                         // Throw an exception
307                         throw new FormClosedException (array($this, "submit"), self::EXCEPTION_CLOSED_FORM);
308                 }
309
310                 // Generate the content
311                 $inputContent = sprintf("<input type=\"submit\" class=\"submit_button\" id=\"%s_submit\" name=\"%s_button\" value=\"%s\" />",
312                         $this->formName,
313                         $this->formName,
314                         $buttonText
315                 );
316
317                 // And add it
318                 $this->addContent($inputContent);
319         }
320
321         /**
322          * Add a form group or close an already opened and open a new one
323          *
324          * @param       $groupName      Name of the group
325          * @param       $groupText      Text including HTML to show above this group
326          * @return      void
327          * @throws      FormClosedException             If no form has been opened before
328          * @throws      EmptyVariableException  If $groupName is not set
329          */
330         public function addFormGroup ($groupName, $groupText) {
331                 // Is a form opened?
332                 if ($this->formOpened === false) {
333                         // Throw exception here
334                         throw new FormClosedException(array($this, $groupName), self::EXCEPTION_CLOSED_FORM);
335                 }
336
337                 // At least the group name should be set
338                 if ((empty($groupName)) && ($this->groupOpened === false)) {
339                         // Throw exception here
340                         throw new EmptyVariableException(array($this, 'groupName'), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
341                 }
342
343                 // Initialize content with closing div by default
344                 $content = "    </div>\n</div><!-- Group - CLOSE //-->";
345
346                 // Is this group opened?
347                 if ($this->groupOpened === false) {
348                         // Begin the div/span blocks
349                         $content = sprintf("<!-- Group %s - OPEN //-->
350 <div class=\"group_box\" id=\"%s_group_box\">
351         <span class=\"group_text\" id=\"%s_group_text\">
352                 %s
353         </span>
354         <div class=\"group_field\" id=\"%s_group_field\">",
355                                 $groupName,
356                                 $groupName,
357                                 $groupName,
358                                 $groupText,
359                                 $groupName
360                         );
361
362                         // Add the content
363                         $this->addContent($content);
364
365                         // Switch the state
366                         $this->groupOpened = true;
367                 } else {
368                         // Is a sub group opened?
369                         if ($this->subGroupOpened === true) {
370                                 // Close it here
371                                 $this->addFormSubGroup("", "");
372                         }
373
374                         // Add the content
375                         $this->addContent($content);
376
377                         // Switch the state
378                         $this->groupOpened = false;
379
380                         // All call it again if the group name is not empty
381                         if (!empty($groupName)) {
382                                 $this->addFormGroup($groupName, $groupText);
383                         }
384                 }
385         }
386
387         /**
388          * Add a form sub group or close an already opened and open a new one or
389          * throws an exception if no group has been opened before or if the sub
390          * group name is empty.
391          *
392          * @param       $subGroupName   Name of the group
393          * @param       $subGroupText   Text including HTML to show above this group
394          * @return      void
395          * @throws      FormGroupClosedException        If no group has been opened before
396          * @throws      EmptyVariableException          If $subGroupName is not set
397          */
398         public function addFormSubGroup ($subGroupName, $subGroupText) {
399                 // Is a group opened?
400                 if ($this->groupOpened === false) {
401                         // Throw exception here
402                         throw new FormGroupClosedException(array($this, $subGroupName), self::EXCEPTION_UNEXPECTED_CLOSED_GROUP);
403                 }
404
405                 // At least the sub group name should be set
406                 if ((empty($subGroupName)) && ($this->subGroupOpened === false)) {
407                         // Throw exception here
408                         throw new EmptyVariableException(array($this, 'groupName'), self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
409                 }
410
411                 // Initialize content with closing div by default
412                 $content = "    </div>\n</div><!-- Sub group- CLOSE //-->";
413
414                 // Is this group opened?
415                 if ($this->subGroupOpened === false) {
416                         // Begin the span block
417                         $content = sprintf("<!-- Sub group %s - OPEN //-->
418 <div class=\"subgroup_box\" id=\"%s_subgroup_box\">
419         <span class=\"subgroup_text\" id=\"%s_subgroup_text\">
420                 %s
421         </span>
422         <div class=\"subgroup_field\" id=\"%s_subgroup_field\">",
423                                 $subGroupName,
424                                 $subGroupName,
425                                 $subGroupName,
426                                 $subGroupText,
427                                 $subGroupName
428                         );
429
430                         // Add the content
431                         $this->addContent($content);
432
433                         // Switch the state and remeber the name
434                         $this->subGroupOpened = true;
435                         $this->subGroupName = $subGroupName;
436                 } else {
437                         // Add the content
438                         $this->addContent($content);
439
440                         // Switch the state
441                         $this->subGroupOpened = false;
442
443                         // All call it again if sub group name is not empty
444                         if (!empty($subGroupName)) {
445                                 $this->addFormSubGroup($subGroupName, $subGroupText);
446                         }
447                 }
448         }
449
450         /**
451          * Add text surrounded by a span block when there is a group opened before
452          * or else by a div block.
453          *
454          * @param       $fieldName                      Field name
455          * @param       $fieldText                      Text for the field
456          * @return      void
457          * @throws      FormClosedException             If the form is not yet opened
458          */
459         public function addFieldText ($fieldName, $fieldText) {
460                 // Is the form opened?
461                 if ($this->formOpened === false) {
462                         // Throw an exception
463                         throw new FormClosedException (array($this, $fieldName), self::EXCEPTION_CLOSED_FORM);
464                 }
465
466                 // Set the block type
467                 $block = "div";
468                 if ($this->groupOpened === true) $block = "span";
469
470                 // Generate the content
471                 $inputContent = sprintf("       <%s id=\"%s_text\">
472                 %s
473         </%s>",
474                         $block,
475                         $fieldName,
476                         $fieldText,
477                         $block
478                 );
479
480                 // And add it
481                 $this->addContent($inputContent);
482         }
483
484         /**
485          * Add text (notes) surrounded by a div block. Still opened groups or sub
486          * groups will be automatically closed.
487          *
488          * @param       $formNotes      The form notes we shell addd
489          * @return      void
490          * @throws      FormClosedException             If the form is not yet opened
491          */
492         public function addFormNote ($formNotes) {
493                 // Is the form opened?
494                 if ($this->formOpened === false) {
495                         // Throw an exception
496                         throw new FormClosedException (array($this, "form_notes"), self::EXCEPTION_CLOSED_FORM);
497                 }
498
499                 // Is a group open?
500                 if ($this->groupOpened === true) {
501                         // Then automatically close it here
502                         $this->addFormGroup("unknown", "");
503                 }
504
505                 // Generate the content
506                 $inputContent = sprintf("       <div id=\"form_note\">
507                 %s
508         </div>",
509                         $formNotes
510                 );
511
512                 // And add it
513                 $this->addContent($inputContent);
514         }
515
516         /**
517          * Checks wether the registration requires a valid email address
518          *
519          * @return      $required       Wether the email address is required
520          */
521         public function ifRegisterRequiresEmailVerification () {
522                 $required = ($this->getConfigInstance()->readConfig('register_requires_email') == "Y");
523                 return $required;
524         }
525
526         /**
527          * Checks wether profile data shall be asked
528          *
529          * @return      $required       Wether profile shall be asked
530          */
531         public function ifRegisterIncludesProfile () {
532                 $required = ($this->getConfigInstance()->readConfig('register_includes_profile') == "Y");
533                 return $required;
534         }
535
536         /**
537          * Checks wether personal data shall be asked
538          *
539          * @return      $required       Wether personal data shall be asked
540          */
541         public function ifRegisterIncludesPersonaData () {
542                 $required = ($this->getConfigInstance()->readConfig('register_personal_data') == "Y");
543                 return $required;
544         }
545
546         /**
547          * Checks wether the specified chat protocol is enabled in this form
548          *
549          * @return      $required       Wether the specified chat protocol is enabled
550          */
551         public function ifChatEnabled ($chatProtocol) {
552                 $required = ($this->getConfigInstance()->readConfig(sprintf("chat_enabled_%s", $chatProtocol)) == "Y");
553                 return $required;
554         }
555
556         /**
557          * Flushs the content out (not yet secured against open forms, etc.!) or
558          * throw an exception if it is not yet closed
559          *
560          * @return      void
561          * @throws      FormOpenedException             If the form is still open
562          */
563         public function flushContent () {
564                 // Is the form still open?
565                 if ($this->formOpened === true) {
566                         // Throw an exception
567                         throw new FormOpenedException ($this, self::EXCEPTION_OPENED_FORM);
568                 }
569
570                 // Send content to template engine
571                 $this->getTemplateInstance()->assignVariable($this->formName, $this->getContent());
572         }
573 }
574
575 // [EOF]
576 ?>