/** * FormHandler::_getForm() * * Private: get the form * * @return string: the generated form * @author Teye Heimans * @author Marien den Besten */ private function getForm($iDisplayPage = null) { //process page // is no specific page requested, then get the "current" page $iDisplayPage = is_null($iDisplayPage) ? $this->pageCurrent : $iDisplayPage; // make sure that the requested page cannot be negative $iDisplayPage = $iDisplayPage <= 0 ? 1 : $iDisplayPage; // set the tab indexes for the fields... reset($this->tabIndexes); ksort($this->tabIndexes); while (list($index, $field) = each($this->tabIndexes)) { // check if the field exists in the form ? if ($this->fieldExists($field)) { // set the tab index $this->getField($field)->setTabIndex($index); } else { trigger_error('Error, try to set the tabindex of an unknown field "' . $field . '"!', E_USER_NOTICE); } } // set the focus to the first (tab index) field if no focus is set yet // and are there tab indexes set ? if (is_null($this->focus) && is_null($this->focusBuffer) && sizeof($this->tabIndexes) > 0) { // set the focus to the element with the lowest positive tab index reset($this->tabIndexes); while (list($key, $field) = each($this->tabIndexes)) { if ($key >= 0 && $this->setFocus($field)) { break; } } } // no focus set yet. Set the focus to the first field if (is_null($this->focus) && is_null($this->focusBuffer)) { // is it a object (only fields + buttons are objects) $ft = array_keys($this->fields); foreach ($ft as $name) { if (!is_null($this->getField($name)) && method_exists($this->getField($name), 'getViewMode') && $this->getField($name)->getViewMode() === false && $this->setFocus($name)) { break; } } } // initialize the used vars $hidden = ''; $form = ''; $buffer = array(); $repeat = true; $page = 1; $fields_displayed = array(); // start a new mask loader $mask = new MaskLoader(); // set the seach values $mask->setSearch(array('/%field%/', '/%error%/', '/%title%/', '/%seperator%/', '/%name%/', '/%error_id%/', '/%value%/', '/%help%/', '/%field_wrapper%/')); // walk trought the fields array foreach ($this->fields as $id => $field) { list($title, $obj) = $field; if ($title == '__PAGE__') { $page++; continue; } if ($title == '__HIDDEN__') { $hidden .= $obj->getField() . "\n"; $hidden .= $obj->getErrorMessage() . "\n"; $fields_displayed[] = $id; continue; } if ($title == '__MASK__') { // new mask to set if (!isset($this->mask) || is_null($this->mask) || $page == $iDisplayPage) { list($this->mask, $repeat) = $obj; } continue; } if ($title == '__HTML__' || $title == '__LINE__') { // but only if the html or line is on this page! if ($page == $iDisplayPage) { $form .= $obj; } continue; } if ($title == '__FIELDSET__') { // begin new fieldset if ($page == $iDisplayPage) { array_unshift($obj, $form); array_push($buffer, $obj); $form = ''; } continue; } if ($title == '__FIELDSET-END__') { // end new fieldset if ($page == $iDisplayPage) { if (sizeof($buffer) > 0) { $d = array_pop($buffer); $form = $d[0] . str_replace(array('%name%', '%caption%', '%content%', '%extra%'), array($d[1], $d[2], $form, $d[3]), Configuration::get('fieldset_mask')); } else { trigger_error('Fieldset is closed while there is not an open fieldset!'); } } continue; } // the fields are not displayed in this page.. // set them as hidden fields in the form if ($page != $iDisplayPage) { // put the data of the field in a hidden field // buttons are just ignored if ($title != '__BUTTON__') { // create a new hidden field to set the field's value in $value = $obj->getValue(); $h = new Field\Hidden($this, $id); $h->setValue($value); $hidden .= $h->getField() . "\n"; unset($h); } break; } // the field is on the current page of the form //create array to know which fields are displayed //used for linked fields $fields_displayed[] = $id; // set the mask which should be filled $mask->setMask($this->mask); // buttons don't have a title :-) if ($title == '__BUTTON__') { $title = ''; } //From this point, we are collecting the data to fill the mask. // Get the field or button value // can we get a field ? if (is_object($obj) && method_exists($obj, 'getField')) { $fld = $obj->getField(); } elseif (is_object($obj) && method_exists($obj, 'getButton')) { $fld = $obj->getButton(); } else { $fld = ''; } // escape dangerous characters $fld = str_replace('%', '____FH-percent____', $fld); // get possible error message $error = ''; if ($this->displayErrors && is_object($obj) && method_exists($obj, 'getErrorState') && $obj->getErrorState() && method_exists($obj, 'getErrorMessage') && $obj->getErrorMessage() != '') { $error = $obj->getErrorMessage(); } // save the error messages // (when the user wants to use his own error displayer) $this->errors[$id] = $error; /** * Get the value for of the field */ $value = ''; if (is_object($obj) && method_exists($obj, 'getValue')) { if (is_array($obj->getValue())) { $value = '__FH_JSON__' . json_encode($obj->getValue()); } else { $value = $obj->getValue(); } } //process help $is_view = method_exists($obj, 'getViewMode') && $obj->getViewMode(); $help = !$this->isViewMode() && !$is_view ? $this->processHelp($id) : ''; // give the field a class error added 25-08-2009 in order to give the field the error mask if ($this->isPosted() == true && $error != '') { $fld = $this->parseErrorFieldStyle($fld); } // now, put all the replace values into an array $replace = array($fld, $error, !empty($title) ? $title : "", !strlen($title) ? '' : ':', !empty($id) ? $id : '', !empty($id) ? 'error_' . $id : '', $value, $help, $id . '_field'); // fill the mask $html = $mask->fill($replace); // added 07-01-2009 in order to specify which element should get the error class if ($this->isPosted() == true && $error != '') { $html = $this->parseErrorStyle($html); } else { $html = str_replace('%error_style%', '', $html); } // is the mask filled ? if ($html) { // add it the the form HTML $form .= str_replace('____FH-percent____', '%', $html); // if we don't have to repeat the current mask, use the original if (!$repeat) { $this->mask = Configuration::get('default_row_mask'); } elseif (is_numeric($repeat)) { $repeat--; } } } //there are linked select fields to create javascript if (count($this->attachSelect) > 0) { //set variables $groups = array(); $group_parents = array(); $item_parents = array(); //loop through all linked fields foreach ($this->attachSelect as $fld => $fields) { //loop through all chained fields foreach ($fields as $chained) { //when both fields are in viewmode exclude from attaching if ($this->fieldExists($chained) && $this->isFieldViewMode($chained)) { continue; } //find parent for this field $check = $fld; //do not go deeper than 500 iterations for ($i = 1; $i <= 500; $i++) { if (!array_key_exists($check, $group_parents)) { break; } $check = $group_parents[$check]; } //add to lookup table $group_parents[$chained] = $check; //when no group is available, create on if (!array_key_exists($check, $groups)) { $groups[$check] = array(); } //only add to group if not added before if (!in_array($chained, $groups[$check])) { //fill $groups[$check][] = $chained; } $item_parents[$chained . '_' . $check] = $fld; //convert master into chained field if (array_key_exists($chained, $groups)) { foreach ($groups[$chained] as $old) { //only add to the group if not already existing if (!in_array($old, $groups[$check])) { //add to existing parent $groups[$check][] = $old; } //change parent lookup $group_parents[$old] = $check; $item_parents[$old . '_' . $check] = $chained; unset($item_parents[$old . '_' . $chained]); } //remove old unset($groups[$chained]); } } } $new_js = ''; //attach loaders foreach ($this->attachSelect as $field_from => $fields) { $extras = array(); $checked_fields = array(); $already_processed = array(); foreach ($fields as $field_to) { //don't include field when field is in view mode if (substr($field_to, 0, 1) != '#' && ($this->isFieldViewMode($field_to) || array_search($field_to, $fields_displayed) === false)) { continue; } //field can be used $checked_fields[] = $field_to; $extraCheck = $this->fieldLinks[$field_from . '_' . $field_to]['extra']; $extraList = !is_array($extraCheck) ? array() : $extraCheck; //process extra's foreach ($extraList as $extra) { if (in_array($extra, $already_processed)) { continue; } // is this argument a field? Then load the value if ($this->fieldExists($extra) == true) { $extra_value = "'+ FormHandler.getValue(\$('" . $this->getFieldHtmlLocator($extra) . "')) +'"; if ($this->isFieldViewMode($extra)) { //when in viewmode the value is not present in the form $extra_value = urlencode($this->getValue($extra)); } $extras[] = $extra . '=' . $extra_value; } else { // just load the extra argument, it's a js string $extras[] = $extra; } $already_processed[] = $extra; } } if (count($checked_fields) == 0) { continue; } $function_name = str_replace('-', '_', $field_from); $field = $this->getField($field_from); $field_class = get_class($this->fields[$field_from][1]); $view_mode = $field instanceof Field\Hidden || $this->isFieldViewMode($field_from); //determine value $from_value = "FormHandler.getValue(\$('" . $this->getFieldHtmlLocator($field_from) . "'),true)"; if ($view_mode) { $from_value = json_encode($this->getValue($field_from)); if (is_array($this->getValue($field_from))) { $from_value = "'__FH_JSON__" . $from_value . "'"; } } $new_js .= 'var field_' . $function_name . ' = $(\'' . $this->getFieldHtmlLocator($field_from) . '\');' . "\n"; if (!$view_mode) { $new_js .= "field_" . $function_name; $new_js .= ".on('" . $this->getFieldTrigger($field_from) . "',function(event,values)\n"; if ($field instanceof Field\Text || $field instanceof Field\Email || $field instanceof Field\Number) { //on text fields we want a delay to prevent server load $new_js .= "{\n"; $new_js .= "clearTimeout(\$.data(this, 'timer'));\n"; $new_js .= " if(event.keyCode == 13) search_" . $function_name . "(values);\n"; $new_js .= " else \$(this).data('timer', setTimeout(function() { " . "search_" . $function_name . "(values); },500));\n"; $new_js .= "});\n"; $new_js .= "function search_" . $function_name . "(values)\n"; } } else { $new_js .= "function load_" . $function_name . "(values)\n"; } $protocol = isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http'; //build request url $request_url = Utils::buildRequestUrl($protocol, $_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI']); $new_js .= "{\n"; $new_js .= " FormHandler.load(\n"; $new_js .= " '" . $request_url . "',\n"; $new_js .= " " . $from_value . ",\n"; $new_js .= " " . json_encode($checked_fields) . ",\n"; $new_js .= " '" . implode('&', $extras) . "',\n"; $new_js .= " values,\n"; $new_js .= " field_" . $function_name . ",\n"; $new_js .= " " . json_encode($this->getFormName()) . ",\n"; $new_js .= " " . json_encode($field_from) . "\n"; $new_js .= " );\n"; $new_js .= "}"; if (!$view_mode && !$field instanceof Field\Text && !$field instanceof Field\Email && !$field instanceof Field\Number) { $new_js .= ");"; } $new_js .= "\n"; } //call loaders foreach ($groups as $parent => $childs) { if (array_search($parent, $fields_displayed) === false) { continue; } $values = array("fh_initial" => 1); foreach ($childs as $child) { $values[$child] = $this->getValue($child); } if (!$this->isFieldViewMode($parent) && !get_class($this->fields[$parent][1]) instanceof Field\Hidden) { $trigger = $this->getFieldTrigger($parent); $trigger = explode(' ', $trigger); $new_js .= "\$('" . $this->getFieldHtmlLocator($parent) . "')"; $new_js .= ".triggerHandler('" . $trigger[0] . "'," . json_encode($values) . ");\n"; } else { $new_js .= "load_" . str_replace('-', '_', $parent) . "(" . json_encode($values) . ");\n"; } } $this->_setJS($new_js, false, false); } // add the page number to the forms HTML if ($this->pageCounter > 1) { $h = new Field\Hidden($this, $this->name . '_page'); $h->setValue($iDisplayPage); $hidden .= $h->getField() . "\n"; unset($h); } // get a possible half filled mask and add it to the html $form .= str_replace('____FH-percent____', '%', $mask->fill(null)); // delete the mask loader unset($mask); // set the javascript needed for setting the focus if ((!empty($this->focus) || !empty($this->focusBuffer)) && $this->focus !== false) { $focus = !empty($this->focus) ? $this->focus : $this->focusBuffer; $this->_setJS("var elem = \$('#" . $this->getField($focus)->getFocus() . "') \n" . "if(elem.length != 0 && elem.is(':hidden') == false) { elem.focus(); }\n", 0, 0); } if ($this->rememberFormPosition === true) { $this->_setJS("if(\$('#" . $this->name . "_position').val() != 0) setTimeout(function()" . "{ \$(document).scrollTop(\$('#" . $this->name . "_position').val()); },200);\n", false, false); $this->_setJS("\$('#" . $this->name . "').on('submit',function()" . "{ \$('#" . $this->name . "_position').val(\$(document).scrollTop()); });\n", false, false); } if (count($this->fieldsHidden) != 0) { foreach (array_keys($this->fieldsHidden) as $field) { $this->setCss('#' . $field . '_field {display:none;}'); } } //get defined CSS $css_defined = $this->getCssCode(); $css = trim($css_defined) != '' ? "<style>\n" . $css_defined . "</style>\n" : ''; // NOTE!! // DO NOT REMOVE THIS! // You can remove the line "This form is generated by FormHandler" with the config!! // DONT REMOVE THE HTML CODE BELOW! // Just use FormHandler::configuration::set('expose', false); before using any FormHandler object $sHeader = "<!--\n" . " This form is automaticly being generated by FormHandler v4.\n" . " See for more info: http://www.formhandler.net\n" . " This credit MUST stay intact for use\n" . "-->\n" . $css . $this->getJavascriptCode(true) . '<form data-fh="true" id="' . $this->name . '" method="post" action="' . \FormHandler\Utils::html($this->action) . '"' . ($this->encoding === self::ENCODING_MULTIPART ? ' enctype="multipart/form-data"' : '') . (!empty($this->extra) ? " " . $this->extra : "") . ">\n" . '<ins>' . "\n" . $hidden . '</ins>'; $sFooter = (Configuration::get('expose') ? "<p><span style='font-family:tahoma;font-size:10px;color:#B5B5B5;font-weight:normal;'>" . 'This form is generated by </span><a href="http://www.formhandler.net" >' . '<span style="font-family:Tahoma;font-size:10px;color:#B5B5B5;">' . '<strong>FormHandler</strong></span></a></p>' : '') . "</form>\n" . "<!--\n" . " This form is automaticly being generated by FormHandler v4.\n" . " See for more info: http://www.formhandler.net\n" . "-->" . $this->getJavascriptCode(false); $search = array('%header%', '%footer%'); $replace = array($sHeader, $sFooter); $new_form = str_replace($search, $replace, $form, $num_replaced); if ($num_replaced === 2) { return $new_form; } else { return $sHeader . $form . $sFooter; } }
/** * FormHandler::_getForm() * * Private: get the form * * @return string: the generated form * @access public * @author Teye Heimans */ function _getForm($iDisplayPage = null) { // is no specific page requested, then get the "current" page if (is_null($iDisplayPage)) { $iDisplayPage = $this->_curPage; } // make sure that the requested page cannot be negative if ($iDisplayPage <= 0) { $iDisplayPage = 1; } // set the tab indexes for the fields... reset($this->_tabindexes); ksort($this->_tabindexes); while (list($index, $field) = each($this->_tabindexes)) { // check if the field exists in the form ? if ($this->fieldExists($field)) { // set the tab index $this->_fields[$field][1]->setTabIndex($index); } else { trigger_error('Error, try to set the tabindex of an unknown field "' . $field . '"!', E_USER_NOTICE); } } // set the focus to the first (tab index) field if no focus is set yet if (is_null($this->_focus)) { // are there tab indexes set ? if (sizeof($this->_tabindexes) > 0) { // set the focus to the element with the lowest positive tab index reset($this->_tabindexes); while (list($key, $field) = each($this->_tabindexes)) { if ($key >= 0 && $this->setFocus($field)) { break; } } } // no focus set yet. Set the focus to the first field if (is_null($this->_focus)) { // is it a object (only fields + buttons are objects) foreach ($this->_fields as $name => $data) { if (is_object($this->_fields[$name][1]) && $this->setFocus($name)) { break; } } } } // initialize the used vars $hidden = ''; $form = ''; $buffer = array(); $repeat = true; $page = 1; // start a new mask loader $mask = new MaskLoader(); // set the seach values $mask->setSearch(array('/%field%/', '/%error%/', '/%title%/', '/%seperator%/', '/%name%/', '/%error_id%/', '/%value%/', '/%help%/')); // walk trought the fields array foreach ($this->_fields as $id => $field) { switch ($field[0]) { // multiple pages in this form case '__PAGE__': # why did we stop at the current page ? //if( $field[1] == $iDisplayPage) //{ // break; //} $page++; break; // hidden field // hidden field case '__HIDDEN__': $hidden .= $field[1]->getField() . "\n"; $hidden .= $field[1]->getError() . "\n"; break; // new mask to set // new mask to set case '__MASK__': if (!isset($this->_mask) || is_null($this->_mask) || $page == $iDisplayPage) { list($this->_mask, $repeat) = $field[1]; } break; // insert html or a line // insert html or a line case '__HTML__': case '__LINE__': // but only if the html or line is on this page! if ($page == $iDisplayPage) { $form .= $field[1]; } break; // begin new fieldset // begin new fieldset case '__FIELDSET__': if ($page == $iDisplayPage) { array_unshift($field[1], $form); array_push($buffer, $field[1]); $form = ''; } break; // end new fieldset // end new fieldset case '__FIELDSET-END__': if ($page == $iDisplayPage) { if (sizeof($buffer) > 0) { $d = array_pop($buffer); $form = $d[0] . str_replace(array('%name%', '%caption%', '%content%', '%extra%'), array($d[1], $d[2], $form, $d[3]), FH_FIELDSET_MASK); } else { trigger_error('Fieldset is closed while there is not an open fieldset!'); } } break; // default action: field or button // default action: field or button default: // the fields are not displayed in this page.. // set them as hidden fields in the form if ($page != $iDisplayPage) { // put the data of the field in a hidden field // buttons are just ignored if ($field[0] != '__BUTTON__') { // create a new hidden field to set the field's value in $h = new HiddenField($this, $id); $value = $field[1]->getValue(); $h->setValue(is_array($value) ? implode(', ', $value) : $value); $hidden .= $h->getField() . "\n"; unset($h); } } else { // set the mask which should be filled $mask->setMask($this->_mask); // easy names for the data $title = $field[0]; $obj =& $field[1]; $name = $id; // buttons don't have a title :-) if ($title == '__BUTTON__') { $title = ''; } /** * From this point, we are collecting the data * to fill the mask. */ // Get the field or button value // can we get a field ? if (is_object($obj) && method_exists($obj, 'getField')) { $fld = $obj->getField(); } else { if (is_object($obj) && method_exists($obj, 'getButton')) { $fld = $obj->getButton(); } else { // trigger error ?? (TODO) $fld = ''; } } // escape dangerous characters $fld = str_replace('%', '____FH-percent____', $fld); /** * Get the error message for this field */ // get possible error message $error = ''; if ($this->_displayErrors && is_object($obj) && method_exists($obj, 'getError')) { // custom error message set and we got an error? if (array_key_exists($name, $this->_customMsg) && $obj->getError() != '') { // use the default error mask ? if ($this->_customMsg[$name][1]) { $error = sprintf(FH_ERROR_MASK, $name, $this->_customMsg[$name][0]); } else { $error = $this->_customMsg[$name][0]; } } else { $error = $obj->getError(); } } // save the error messages // (when the user wants to use his own error displayer) $this->errors[$name] = $error; /** * Get the value for of the field */ $value = ''; if (is_object($obj) && method_exists($obj, 'getValue')) { if (is_array($obj->getValue())) { $value = implode(', ', $obj->getValue()); } else { $value = $obj->getValue(); } } /** * Get the help string */ $help = ''; if (array_key_exists($name, $this->_help) && !$this->isViewMode() && !$this->isFieldViewMode($name)) { if (strpos(FH_HELP_MASK, '%s')) { $help = sprintf(FH_HELP_MASK, $this->_helpIcon, $this->_help[$name][0], str_replace('%title%', addslashes(htmlentities($title, null, FH_HTML_ENCODING)), $this->_help[$name][1])); } else { $help = str_replace(array('%helpicon%', '%helptext%', '%helptitle%'), array($this->_helpIcon, $this->_help[$name][0], str_replace('%title%', addslashes(htmlentities($title, null, FH_HTML_ENCODING)), $this->_help[$name][1])), FH_HELP_MASK); } } // give the field a class error added 25-08-2009 in order to give the field the error mask if ($this->isPosted() == true and $error != '') { $fld = $this->parse_error_Fieldstyle($fld); } // now, put all the replace values into an array $replace = array($fld, $error, !empty($title) ? $title : "", !strlen($title) ? '' : ':', !empty($name) ? $name : '', !empty($name) ? 'error_' . $name : '', $value, $help); // fill the mask $html = $mask->fill($replace); // added 07-01-2009 in order to specify which element should get the error class if ($this->isPosted() == true and $error != '') { $html = $this->parse_error_style($html); } else { $html = str_replace('%error_style%', '', $html); } // is the mask filled ? if ($html) { // add it the the form HTML $form .= str_replace('____FH-percent____', '%', $html); // if we don't have to repeat the current mask, use the original if (!$repeat) { $this->_mask = FH_DEFAULT_ROW_MASK; } else { if (is_numeric($repeat)) { $repeat--; } } } } break; } } // add the page number to the forms HTML if ($this->_pageCounter > 1) { $h = new HiddenField($this, $this->_name . '_page'); $h->setValue($iDisplayPage); $hidden .= $h->getField() . "\n"; unset($h); } // get a possible half filled mask and add it to the html $form .= str_replace('____FH-percent____', '%', $mask->fill(null)); // delete the mask loader unset($mask); // get occured PHP errors $errors = catchErrors(); $errmsg = ''; // walk all error messages foreach ($errors as $error) { switch ($error['no']) { case E_USER_WARNING: $type = 'Warning'; break; case E_USER_NOTICE: $type = 'Notice'; break; case E_USER_ERROR: $type = 'Error'; break; default: $type = 'Warning (' . $error['no'] . ')'; break; } $errmsg .= "<b>" . $type . ":</b> " . basename($error['file']) . " at " . $error['line'] . " " . $error['text'] . "<br />\n"; } // set the javascript needed for setting the focus if ($this->_focus) { $this->_setJS("// set the focus on a specific field \n" . "var elem = document.getElementById ? document.getElementById('" . $this->_focus . "'): document.all? document.all['" . $this->_focus . "']: false; \n" . "if( (elem) && (elem.type != 'hidden')) {\n" . " try {\n" . " elem.focus();\n" . " } catch(e) {}\n" . "}\n", 0, 0); } // NOTE!! // DO NOT REMOVE THIS! // You can remove the line "This form is generated by FormHandler" in the config file!! // DONT REMOVE THE HTML CODE BELOW! Just set FH_EXPOSE to FALSE! $sHeader = $errmsg . "<!--\n" . " This form is automaticly being generated by FormHandler v3.\n" . " See for more info: http://www.formhandler.net\n" . " This credit MUST stay intact for use\n" . "-->\n" . $this->getJavascriptCode(true) . '<form id="' . $this->_name . '" method="post" action="' . htmlentities($this->_action, null, FH_HTML_ENCODING) . '"' . (sizeof($this->_upload) > 0 ? ' enctype="multipart/form-data"' : '') . (!empty($this->_extra) ? " " . $this->_extra : "") . ">\n" . '<ins>' . $hidden . '</ins>' . ($this->_setTable ? sprintf("<table border='%d' cellspacing='%d' cellpadding='%d'%s>\n", $this->_tableSettings['border'], $this->_tableSettings['cellspacing'], $this->_tableSettings['cellpadding'], (!empty($this->_tableSettings['width']) ? " width='" . $this->_tableSettings['width'] . "'" : "") . ' ' . $this->_tableSettings['extra']) : ''); $sFooter = ($this->_setTable ? "\n</table>\n" : '') . (FH_EXPOSE ? "<p><span style='font-family:tahoma;font-size:10px;color:#B5B5B5;font-weight:normal;'>" . 'This form is generated by </span><a href="http://www.formhandler.net" >' . '<span style="font-family:Tahoma;font-size:10px;color:#B5B5B5;"><strong>FormHandler</strong></span></a></p>' . "\n" : '') . "</form>\n" . "<!--\n" . " This form is automaticly being generated by FormHandler v3.\n" . " See for more info: http://www.formhandler.net\n" . "-->" . $this->getJavascriptCode(false); $search = array('%header%', '%footer%'); $replace = array($sHeader, $sFooter); $new_form = str_replace($search, $replace, $form, $num_replaced); if ($num_replaced === 2) { return $new_form; } else { return $sHeader . $form . $sFooter; } }