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