<?php

require_once "validaforms.php";

class formbuilder
{
    public $fields = array();
    public $btnlabel;
    public $formname;
    public $formintro;
    public $submitURL;
    public $Thanks;
    public $formchecked = false;
    public $submitvals = array();
    public $formerrors = array();

    public function FormBuilder($formname, $btnlabel = "send", $formintro = null, $usePseudoLegends = false, $showDividers = false, $submitURL = null)
    {
        $this->btnlabel = $btnlabel;
        $this->formname = $formname;
        $this->formintro = $formintro;
        $this->usePseudoLegends = $usePseudoLegends;
        $this->showDividers = $showDividers;
        $this->submitURL = $submitURL;
        if ($this->submitURL == null) {
            $this->submitURL = $_SERVER["REQUEST_URI"];
        }
        // create instance of valida forms (validation) class
        $this->vFs = new validaForms();

        $this->token_id = $this->get_token_id();
        $this->token_value = $this->get_token($this->token_id);
    }

    public function get_token_id()
    {
        if (isset($_SESSION['token_id'])) {
            return $_SESSION['token_id'];
        } else {
            $token_id = $this->random(10);
            $_SESSION['token_id'] = $token_id;

            return $token_id;
        }
    }

    public function get_token()
    {
        if (isset($_SESSION['token_value'])) {
            return $_SESSION['token_value'];
        } else {
            $token = hash('sha256', $this->random(500));
            $_SESSION['token_value'] = $token;

            return $token;
        }
    }

    public function check_valid($method)
    {
        if ($method == 'post' || $method == 'get') {
            $post = $_POST;
            $get = $_GET;
            if (isset(${$method}[$this->get_token_id()]) && (${$method}[$this->get_token_id()] == $this->get_token())) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public function form_names($names, $regenerate)
    {
        $values = array();
        foreach ($names as $n) {
            if ($regenerate == true) {
                unset($_SESSION[$n]);
            }
            $s = isset($_SESSION[$n]) ? $_SESSION[$n] : $this->random(10);
            $_SESSION[$n] = $s;
            $values[$n] = $s;
        }

        return $values;
    }

    public function form_input_name($name)
    {
        $s = isset($_SESSION[$name]) ? $_SESSION[$name] : $this->random(10);
        $_SESSION[$name] = $s;

        return $s;
    }

    private function random($len)
    {
        $return = '';
        for ($i = 0;$i<$len;++$i) {
            if (!isset($urandom)) {
                if ($i%2 == 0) {
                    mt_srand(time()%2147 * 1000000 + (double) microtime() * 1000000);
                }
                $rand = 48+mt_rand()%64;
            } else {
                $rand = 48+ord($urandom[$i])%64;
            }

            if ($rand>57) {
                $rand += 7;
            }
            if ($rand>90) {
                $rand += 6;
            }

            if ($rand == 123) {
                $rand = 52;
            }
            if ($rand == 124) {
                $rand = 53;
            }
            $return .= chr($rand);
        }

        return $return;
    }

    /**
     *	checkSubmit
     *	===========
     *
     *	Checks if form has been completed correctly
     *
     *	@return bool
     *
     */
    public function checkSubmit()
    {
        $this->formchecked = true;
        $this->rest = false;

        if (isset($_POST['submit']) && isset($_POST['fbformname']) && $_POST['fbformname'] == $this->formname) {
            $rest = array();
            foreach ($this->fields as $field) {
                if (in_array($field['type'], array('fieldset', 'html','collapse')) == false) {

                    $field['name'] = $this->form_names[$field['id']];
                    $post_data = ($field['type'] == 'checkbox') ? $_POST[$field['name'].'_arr'] : $_POST[$field['name']];
                    if (isset($post_data) == false) {
                        $rest[] = true;
                        continue;
                    }

                    if (get_magic_quotes_gpc()) {
                        $_POST[$field['id']] = stripslashes($_POST[$field['name']]);
                    }
                    $errorFound = false;
                    // Use valida forms class for form field validation
                    // First, convert human readable setup variables into valida form values,
                    // and set default values in case  no value was specified
                    $required = (isset($field['required']) && $field['required'] == true) ? 1 : 0;
                    $maxlength = (isset($field['maxlength'])) ? $field['maxlength'] : null;
                    $minlength = (isset($field['minlength'])) ? $field['minlength'] : 0;
                    $invalidvalue = (isset($field['invalidvalue'])) ? $field['invalidvalue'] : null;
                    $headerinjectioncheck = (isset($field['headerinjectioncheck'])) ? $field['headerinjectioncheck'] : null;
                    if (isset($field['validationtype'])) {
                        switch ($field['validationtype']) {
                            case "alpha":
                                $validationtype = 1;
                                break;
                            case "numeric":
                                $validationtype = 2;
                                break;
                            case "alphanumeric":
                                $validationtype = 3;
                                break;
                            case "email":
                                $validationtype = "email";
                                break;
                            default:
                                $validationtype = null;
                        }
                    } else {
                        $validationtype = null;
                    }
                    // now perform the validation
                    if ($field['type'] == "textbox" || $field['type'] == "textarea" || $field['type'] == "password") {
                        if ($validationtype != "email") {
                            if ((!$this->vFs->textBox($field['label'], $_POST[$field['name']], $required, $validationtype, $minlength, $maxlength))) {
                                $errorFound = true;
                            }
                        } else {
                            if ((!$this->vFs->emailCheck($field['label'], $_POST[$field['name']], $required))) {
                                $errorFound = true;
                            }
                        }
                    }
                    if ($field['type'] == "file" || $field['type'] == "imagefile") {
                        if ((!$this->vFs->textBox($field['label'], $_POST[$field['name']], $required, $validationtype, $minlength, $maxlength))) {
                            $errorFound = true;
                        }
                    }
                    if ($field['type'] == "select") {
                        if ((!$this->vFs->selectBox($field['label'], $_POST[$field['name']], $invalidvalue))) {
                            $errorFound = true;
                        }
                    }
                    if ($field['type'] == "radio" && $required == 1) {
                        // in case no radio button was selected, set POST value to null
                        if (!isset($_POST[$field['name']])) {
                            $_POST[$field['name']] = null;
                        }
                        if ((!$this->vFs->radioButton($field['label'], $_POST[$field['name']]))) {
                            $errorFound = true;
                        }
                    }
                    if ($field['type'] == "checkbox") {
                        // This will concatenate all checkboxes with the same name into a comma seperated list,
                        // and copy the result into $_POST[$field['id']]
                        $_POST[$field['name']] = null;
                        if (!isset($_POST[$field['name'].'_arr'])) {
                            $_POST[$field['name'].'_arr'] = null;
                        }
                        if ($required == 1) {
                            if ((!$this->vFs->checkBox($field['label'], $_POST[$field['name'].'_arr']))) {
                                $errorFound = true;
                            } else {
                                // loop through all checkboxes in this 'group' and concatenate their values
                                foreach ($_POST[$field['name'].'_arr'] as $value) {
                                    $_POST[$field['name']] .= $value.',';
                                }
                                // tidy up: strip last comma
                                $_POST[$field['name']] = substr($_POST[$field['name']], 0, strlen($_POST[$field['name']])-1);
                            }
                        }
                    }
                    if ($errorFound) {
                        // Validation error! Push details of the error into our formerrors array for display to the user.
                        array_push($this->formerrors, array('id' => $field['id'], 'errormsg' => $this->vFs->erro));
                    } else {
                        // Form header injection validation
                        if ($headerinjectioncheck == 'full') {
                            if ($this->checkHeaderInjection($_POST[$field['name']])) {
                                array_push($this->formerrors, array('id' => $field['id'], 'errormsg' => 'The \''.$field['label'].'\' field contains formatting that may cause errors processing this form. This may occur if you pasted text into the field from another application, or your text includes "bcc:" or "content-type:".'));
                            }
                        }
                        if ($headerinjectioncheck == 'light') {
                            if ($this->checkHeaderInjectionLight($_POST[$field['name']])) {
                                array_push($this->formerrors, array('id' => $field['id'], 'errormsg' => 'The \''.$field['label'].'\' field contains formatting that may cause errors processing this form. This may occur if your text includes "bcc:" or "content-type:".'));
                            }
                        }
                    }
                }
            }
            if (count($rest) > 0) {
                $this->rest = true;
                $this->formerrors[] = array('id' => 'none' ,'errormsg' => tr('err_processing_form'));
            }
            if (count($this->formerrors) > 0) {
                // there was one or more errors detected by valida forms
                return false;
            }
            // if we got this far, form was successfully validated!
            return true;
        } else {
            // form hasn't been submitted
            return false;
        }
    }
    /**
     *	checkHeaderInjection
     *	====================
     *
     *	Protects form fields against Header Injection attacks
     *
     *	@return bool Returns true if a header injection attack was detected
     *
     */
    public function checkHeaderInjection($value)
    {
        if (preg_match("/%0A/i", $value) || preg_match("/%0D/i", $value) || preg_match("/\r/i", $value) || preg_match("/\n/i", $value) || preg_match("/bcc:/i", $value) || preg_match("/content-type:/i", $value)) {
            return true;
        } else {
            return false;
        }
    }
    /**
     *	checkHeaderInjection
     *	====================
     *
     *	Lightweight header injection protection. For fields that are allowed linebreaks,
     *  but still contain telltale header injection strings.
     *
     *	@return bool Returns true if a header injection attack was detected
     *
     */
    public function checkHeaderInjectionLight($value)
    {
        if (preg_match("/bcc:/i", $value) || preg_match("/content-type:/i", $value)) {
            return true;
        } else {
            return false;
        }
    }
    /**
     *	addFieldSet
     *	===========
     *
     *	Adds a new HTML fieldset and legend to the form
     *
     *	@param string $legend A description for the fieldset, to be rendered in a <legend> tag
     *
     */
    public function addFieldSet($legend)
    {
        $fieldset = array(
            'type' => 'fieldset',
            'legend' => $legend,
        );
        array_push($this->fields, $fieldset);
    }

    public function addCollapse($id, $legend)
    {
        $fieldset = array(
            'id' => $id,
            'type' => 'collapse',
            'legend' => $legend,
        );
        array_push($this->fields, $fieldset);
    }

    /**
     *	closeFieldSet
     *	=============
     *
     *	Closes an HTML fieldset
     *
     *
     */
    public function closeFieldSet()
    {
        $fieldset = array(
            'type' => 'closefieldset',
        );
        array_push($this->fields, $fieldset);
    }
    /**
     *	addField
     *	========
     *
     *	Adds a new HTML form field to the form
     *
     *	@param array $field An array containing all the key/value pairs describing the field
     *
     */
    public function addField($field)
    {
        array_push($this->fields, $field);
        $this->form_names[$field['id']] = $this->form_input_name($field['id'], false);
    }
    /**
     *	forceErrorMessage
     *	=================
     *
     *	Adds a new custom error message to the errors array.
     *  Useful for if you want to do custom form validation
     *  after FormBuilder has completed its own validation,
     *  and want to display an error message to the user.
     *
     *	@param string $fieldId The name of the form field that has the error message
     *	@param string $newError The error message to be displayed to the user
     *
     */
    public function forceErrorMessage($fieldId, $newError)
    {
        array_push($this->formerrors, array('id' => $fieldId, 'errormsg' => $newError));
    }
    /**
     *	renderErrorMessage
     *	=================
     *
     *	Loops through all form validation errors and prints them to screen.
     *  If all regular validation errors are passed then any header injection
     *  errors will be displayed.
     *
     */
    public function renderErrorMessage()
    {
        if (count($this->formerrors)>0) {
            ob_start();
            echo('<div class="fbformerrormessage">');
            echo('<h2>'.tr('err_processing_form').'</h2>');
            echo('<ul>');
            foreach ($this->formerrors as $error) {
                echo('<li>'.$error['errormsg'].'</li>');
            }
            echo('</ul>');
            echo('</div>');
            $html = ob_get_contents();
            ob_end_clean();

            return $html;
        }
    }
    /**
     *	renderThanks
     *	===========
     *
     *	Displays a Thank You message to the user upon successful
     *  processing of the form.
     *
     */
    public function renderThanks($heading = null, $message = null, $showLink = false, $btntarg = null, $btnlabel = null)
    {
        if ($heading == null) {
            $heading = tr('thank_you');
        }
        if ($message == null) {
            $message = tr('form_processed');
        }
        if ($btnlabel == null) {
            $btnlabel = tr('back');
        }
        if ($this->formSuccess()) {
            ob_start();
            echo('<div class="fbthanks">');
            echo('<h2>'.$heading.'</h2>');
            echo('<p>'.$message.'</p>');
            if ($showLink) {
                if ($btntarg == null) {
                    $btntarg = $_SERVER['PHP_SELF'];
                }
                echo('<p><a href="'.$btntarg.'">'.$btnlabel.'</a></p>');
            }
            echo('</div>');
            $html = ob_get_contents();
            ob_end_clean();
            $this->Thanks = $html;
        }
    }
    /**
     *	isSubmitted
     *	===========
     *
     *	Checks if form has been submitted
     *
     *	@return bool
     *
     */
    public function isSubmitted()
    {
        if ($this->formchecked == false) {
            $this->checkSubmit();
        }
        if (isset($_POST['submit']) && isset($_POST['fbformname']) && $_POST['fbformname'] == $this->formname) {
            return true;
        }

        return false;
    }
    /**
     *	formSuccess
     *	===========
     *
     *	Checks to see if the form was subitted and successfully processed.
     *  Useful for selectively showing/hiding HTML content if form was successfully processed.
     *
     *  @return bool
     *
     *
     */
    public function formSuccess()
    {
        if ($this->check_valid('post')) {
            if ($this->formchecked == false) {
                $this->checkSubmit();
            }
            if (isset($_POST['submit'])
                && isset($_POST['fbformname'])
                && $_POST['fbformname'] == $this->formname
                && count($this->formerrors) == 0) {
                    foreach ($this->fields as $field) {
                    	if(isset($this->form_names[$field['id']])){
                    	   $key = ($field['type'] == 'checkbox') ? $field['id'].'_arr' : $field['id'];
                    	   $_POST[$key] = ($field['type'] == 'checkbox') ? $_POST[$this->form_names[$field['id']].'_arr'] : $_POST[$this->form_names[$field['id']]];
                    	}
                    }                    
                return true;
            }
        }

        return false;
    }

    public function renderForm()
    {
        if ($this->isSubmitted()) {
            $old_form_names = $this->form_names;
            $names = array_map(function ($field) { return $field['id']; }, $this->fields);
            $this->form_names = $this->form_names($names, true);

            foreach ($this->form_names as $key => $value) {
                if (isset($_POST[$old_form_names[$key]])) {
                    $_POST[$this->form_names[$key]] = $_POST[$old_form_names[$key]];
                }
            }
        }

        $thisFormSubmitted = false;
        $fieldsetOpen = false;
        $collapseOpen = false;
        $dlOpen = false;
        $loopCount = 0;
        if (isset($_POST['submit']) && isset($_POST['fbformname']) && $_POST['fbformname'] == $this->formname && $this->rest == false) {
            $thisFormSubmitted = true;
        }

        ob_start();

        if (empty($this->Thanks) == false) {
            echo $this->Thanks;
        }

        if ($this->formSuccess() == false) {
            echo $this->renderErrorMessage();
        }
        // Form introduction/instructions
        echo sprintf('<p class="fbintro">%s, %s</p>', $this->formintro, ftr('form_intro', array('<span class="fbrequired">*</span>')));
        // Open form
        echo('<form id="fbform" class="fbform form-horizontal" action="'.$this->submitURL.'" method="post" enctype="multipart/form-data">'."\n");
        // Loop through all form fields
        foreach ($this->fields as $field) {
            $fieldErrorFound = false;
            // Special case: Fieldset
            if ($field['type'] == "fieldset") {
                if ($dlOpen) {
                    echo("\t".'</dl>'."\n");
                    $dlOpen = true;
                }
                // In case another fieldset is open, close it
                if ($fieldsetOpen) {
                    echo('</fieldset>'."\n");
                }
                echo('<fieldset>'."\n");
                if ($this->usePseudoLegends == true) {
                    $legendEle = 'h3';
                } else {
                    $legendEle = 'legend';
                }
                echo("\t".'<'.$legendEle.'>'.$field['legend'].'</'.$legendEle.'>'."\n");
                echo("\t".'<dl>'."\n");
                $fieldsetOpen = true;
                $dlOpen = true;
            // Special case: Close fieldset
            } elseif ($field['type'] == "collapse") {
                if ($collapseOpen) {
                    echo('</div>'."\n");
                }
                echo('<a href="#" data-toggle="collapse" data-target="#'.$field['id'].'" onclick="return false;">+ '.$field['legend'].'</a>'."\n");
                echo('<div id="'.$field['id'].'" class="collapse show-if-no-js">'."\n");
            } elseif ($field['type'] == "closefieldset") {
                if ($dlOpen) {
                    echo("\t".'</dl>'."\n");
                    $dlOpen = true;
                }
                // In case another fieldset is open, close it
                if ($fieldsetOpen) {
                    echo('</fieldset>'."\n");
                }
                $fieldsetOpen = false;
                $dlOpen = false;
            // All regular form fields
            } elseif ($field['type'] != "hidden") {
                $field['name'] = $this->form_names[$field['id']];

                if (!$dlOpen) {
                    echo("\t".'<dl>'."\n");
                    $dlOpen = true;
                }
                // Field label
                echo("\t\t".'<div class="form-group">');

                echo('<label for="'.$field['id'].'" class="col-md-3 control-label');

                if (isset($_POST['submit'])) {
                    foreach ($this->formerrors as $error) {
                        if ($error['id'] == $field['id']) {
                            echo(' fbfielderror');
                            $fieldErrorFound = true;
                            break;
                        }
                    }
                }
                echo('">');
                echo($field['label']);
                if (isset($field['required']) && $field['required'] == true) {
                    if (!$fieldErrorFound) {
                        echo(' <span class="fbrequired">*</span>');
                    } else {
                        echo(' *');
                    }
                }
                echo('</label>');

                echo('<div class="col-md-9">');

                switch ($field['type']) {
                    // Textfield
                    case "textbox":
                        echo("\t\t\t".'<input id="'.$field['id'].'" name="'.$field['name'].'" class="form-control" type="text" placeholder="'.$field['label'].'" ');
                        if (isset($field['maxlength'])) {
                            echo('maxlength="'.$field['maxlength'].'" ');
                        }
                        echo('value="');
                        if ($thisFormSubmitted) {
                            echo(@$_POST[$field['name']]);
                        } elseif (isset($field['defaultvalue'])) {
                            echo($field['defaultvalue']);
                        }
                        echo('" />');
                        break;
                    // Password
                    case "password":
                        echo("\t\t\t".'<input id="'.$field['id'].'" name="'.$field['name'].'" class="form-control" type="password" placeholder="'.$field['label'].'" ');
                        if (isset($field['maxlength'])) {
                            echo('maxlength="'.$field['maxlength'].'" ');
                        }
                        echo('value="');
                        if ($thisFormSubmitted) {
                            echo(@$_POST[$field['name']]);
                        }
                        echo('" />');
                        break;
                    // File
                    case "file":
                    case "imagefile":

                       $has_value = (empty($field['defaultvalue']) == false) ? true : false;
                       $class = ($has_value == false) ? 'input-new' : '';

                            switch ($field['type']) {
                                case 'file':
                                    //echo sprintf('<div data-provides="fileupload" class="fileupload %s"><div class="input-append"><div class="uneditable-input span2"><i class="icon-file fileupload-exists"></i> <span class="fileupload-preview">%s</span></div><span class="btn btn-file"><span class="fileupload-new">إختيار ملف</span><span class="fileupload-exists">تغيير</span><input name="%s" type="file" /></span></div></div>',$class,($has_value == true) ? $field['defaultvalue'] : '',$field['id'] );
                                break;

                                case 'imagefile':
                                    echo sprintf(
                                        '<div class="featured-image-input %s">
                                            <span class="featured-image">%s</span>
                                            <input type="hidden" name="%s" value="%s" />
                                            <button type="button" class="close cancel" role="button">&times;</button>
                                            <button type="button" class="btn btn-sm btn-default btn-block" role="button" data-toggle="modal" data-target="#media-tab">%s</button>
                                        </div>',
                                        $class,
                                        ($has_value == true) ? sprintf('<img class="img-thumbnail" src="%s" />', $field['defaultimage']) : '',
                                        $field['name'],
                                        ($has_value == true) ? $field['defaultvalue'] : 0,
                                        tr('select')
                                    );
                                break;
                            }

                        break;
                    // Textarea
                    case "textarea":
                        if (isset($field['rows'])) {
                            $rows = $field['rows'];
                        } else {
                            $rows = "5";
                        }
                        if (isset($field['cols'])) {
                            $cols = $field['cols'];
                        } else {
                            $cols = "35";
                        }
                        if (isset($field['toolbar'])) {
                            echo('<p>');
                            echo '<button type="button" class="btn btn-xs btn-default" role="button" data-toggle="modal" data-target="#media-tab"><i class="fa fa-image"></i> '.tr('add_media').'</button>';
                            echo('</p>');
                        }
                        echo("\t\t\t".'<textarea id="'.$field['id'].'" name="'.$field['name'].'" class="form-control" rows="'.$rows.'" cols="'.$cols.'">');
                        if ($thisFormSubmitted) {
                            echo(@$_POST[$field['name']]);
                        } elseif (isset($field['defaultvalue'])) {
                            echo($field['defaultvalue']);
                        }
                        echo('</textarea>');

                        break;
                    // Select
                    case "select":
                        echo("\t\t\t".'<select id="'.$field['id'].'" name="'.$field['name'].'" class="form-control">'."\n");
                        for ($n = 0; $n<count($field['optionlabels']);$n++) {
                            echo("\t\t\t\t".'<option value="'.$field['optionvalues'][$n].'"');
                            if ($thisFormSubmitted) {
                                if ($_POST[$field['name']] == $field['optionvalues'][$n]) {
                                    echo(' selected="selected"');
                                }
                            } elseif (isset($field['defaultvalue']) && $field['optionvalues'][$n] == $field['defaultvalue']) {
                                echo(' selected="selected"');
                            }
                            echo('>'.$field['optionlabels'][$n].'</option>'."\n");
                        }
                        echo("\t\t\t".'</select>'."\n");
                        break;
                    // Radio buttons
                    case "radio":
                        for ($n = 0; $n<count($field['radiolabels']);$n++) {
                            echo("\t\t\t".'<div class="radio"><label>'."\n");
                            echo("\t\t\t\t".'<input name="'.$field['name'].'" type="radio" value="'.$field['radiovalues'][$n].'"');
                            if ($thisFormSubmitted) {
                                if (isset($_POST[$field['name']]) && $_POST[$field['name']] == $field['radiovalues'][$n]) {
                                    echo(' checked="checked"');
                                }
                            } elseif (isset($field['defaultvalue']) && $field['radiovalues'][$n] == $field['defaultvalue']) {
                                echo(' checked="checked"');
                            }
                            echo(' /> ');
                            echo($field['radiolabels'][$n]."\n");
                            echo("\t\t\t".'</label></div>'."\n");
                        }
                        break;
                    // Checkboxes
                    case "checkbox":
                        for ($n = 0; $n<count($field['checkboxlabels']);$n++) {
                            echo("\t\t\t".'<div class="checkbox"><label>'."\n");
                            echo("\t\t\t\t".'<input name="'.$field['name'].'_arr[]" class="fbcheckbox" type="checkbox" value="'.$field['checkboxvalues'][$n].'"');
                            if ($thisFormSubmitted) {
                                if (isset($_POST[$field['name'].'_arr'])) {
                                    foreach ($_POST[$field['name'].'_arr'] as $value) {
                                        if ($value == $field['checkboxvalues'][$n]) {
                                            echo(' checked="checked"');
                                        }
                                    }
                                }
                            } elseif (isset($field['checkboxchecked']) && $field['checkboxchecked'][$n] == true) {
                                // if checkbox is supposed to be checked by default
                                echo(' checked="checked"');
                            }
                            echo(' /> ');
                            echo($field['checkboxlabels'][$n]."\n");
                            echo("\t\t\t".'</label></div>'."\n");
                        }
                    break;

                    case "html":
                        echo($field['html']."\n");
                    break;
                }

                // Render Instructions
                if (isset($field['instructions'])) {
                    echo("\n\t\t\t".'<div class="help-block">'.$field['instructions'].'</div>');
                }

                echo("\n\t\t".'</div></div>'."\n");

                if ($this->showDividers == true) {
                    echo("\t\t".'<dd class="fbformdivider');
                    if ($loopCount+1<count($this->fields)) {
                        if ($this->fields[$loopCount+1]['type'] == "fieldset" || $this->fields[$loopCount+1]['type'] == "closefieldset") {
                            echo(' fblast');
                        }
                    }
                    echo('">&nbsp;</dd>'."\n");
                }
            }
            $loopCount++;
        }
        echo("\n\t".'</dl>'."\n");
        if ($fieldsetOpen) {
            echo('</fieldset>'."\n");
        }
        if ($collapseOpen) {
            echo('</div>'."\n");
        }
        echo('<fieldset class="fbsubmit">'."\n");
        // All hidden variables
        foreach ($this->fields as $field) {
            if ($field['type'] == "hidden") {
                $field['name'] = $this->form_names[$field['id']];
                echo('<input id="'.$field['id'].'" name="'.$field['name'].'" type="hidden" value="'.$field['value'].'" />'."\n");
            }
        }
        // Form name hidden variable
        // (in case there is more than one form, we need to be able to tell them apart)
        echo('<input name="'.$this->token_id.'" type="hidden" value="'.$this->token_value.'" />'."\n");
        echo('<input name="fbformname" type="hidden" value="'.$this->formname.'" />'."\n");
        // Submit Button
        echo('<input id="submit" type="submit" name="submit" value="'.$this->btnlabel.'" class="btn btn-sm btn-default" />'."\n");
        echo('</fieldset>'."\n");
        // close form
        echo('</form>'."\n");

        $html = ob_get_contents();
        ob_end_clean();

        return $html;
    }
}
