<commit_before><?php

require_once("View.php");
require_once("GenericParameter.php");
require_once("PostParameter.php");
require_once("vendor/smarty/smarty/libs/Smarty.class.php");

/**
 * The object oriented and template based norm form is used to gather, validate and process form data in a flexible way.
 *
 * This abstract class represents a well known process of gathering, validating and processing form data within a single
 * PHP structure. To use it, simple extend this class and implement the abstract methods isValid() (for validation) and
 * business() for processing/business logic. Then create an object of your subclass, supply a View object and start
 * the process by calling normForm.
 * The initial call will show the form supplied by the View object. Submitted form data will then be validated by your
 * implementation of isValid(). Occurring error messages can be passed on to the View object and displayed in the
 * template output. Once validation is passed, the data entered in the form can be processed in business() in any
 * suitable way. By returning a new View object in business() the processed data can be displayed flexibly (in a new
 * template or in a separate file). If nothing is returned the current (form) view also can be used to show output.
 *
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @version 2017
 */
abstract class AbstractNormForm
{

    /**
     * @var Smarty $smarty Hold the reference to the Smarty template engine.
     */
    protected $smarty;

    /**
     * @var View $currentView Holds the currently supplied View object that will be used in the template to render
     * output.
     */
    protected $currentView;

    /**
     * @var array $errorMessages An array containing all error messages being set by isValid().
     */
    protected $errorMessages;

    /**
     * @var string $statusMessage An optional status message that can be set in business() when processing data was
     * successful.
     */
    protected $statusMessage;

    /**
     * Abstract method used to validate the form input. Must be implemented in the subclass.
     * @return bool Returns true if validation was successful, otherwise false.
     */
    abstract protected function isValid(): bool;

    /**
     * Abstract method for processing the validated form input (a.k.a. business logic). Must be implemented in the
     * subclass.
     * @return View|null Can return a View object to determine a new target for output or null to keep the same view.
     */
    abstract protected function business();

    /**
     * Creates a new instance for a norm form object and initializes all necessary fields. A View object is used to
     * initially define how and where output is displayed via the template engine and supply parameters to the template.
     * The template engine itself is also set up, two optional parameters allow setting the template paths.
     * @param View $defaultView Holds the initial @View object used for displaying the form.
     * @param string $templateDir Optional parameter for setting the path to the template files.
     * @param string $compileDir Optional parameter for setting the path for compiled templates.
     */
    public function __construct(
        View $defaultView,
        string $templateDir = "templates",
        string $compileDir = "templates_c"
    ) {
        $this->smarty = new Smarty();
        $this->smarty->template_dir = $templateDir;
        $this->smarty->compile_dir = $compileDir;
        $this->currentView = $defaultView;
        $this->errorMessages = [];
        $this->statusMessage = "";
    }

    /**
     * Main "decision" method for the form processing. This decision tree uses isFormSubmission() to check if the form
     * is being initially displayed or shown again after a form submission and either calls show() to display the form
     * (using the supplied View object) or validate the received input in isValid(). If validation failed, show() is
     * called again. Possible error messages provided as parameters to the View object in isValid() can now be
     * displayed. Once the submission was correct, business() is called where the data can be processed as needed. If
     * this method returns a new View object it is used to display the output as specified there, otherwise the current
     * view is kept.
     */
    public function normForm()
    {
        if ($this->isFormSubmission()) {
            if ($this->isValid()) {
                $view = $this->business();
                $this->show($view);
            } else {
                $this->show();
            }
        } else {
            $this->show();
        }
    }

    /**
     * Checks if the current request was an initial one (thus using GET) or a recurring one after a form submission
     * (where POST was used).
     * @return bool Returns true if a form was submitted or false if it was an initial call.
     */
    protected function isFormSubmission(): bool
    {
        return ($_SERVER["REQUEST_METHOD"] === "POST");
    }

    /**
     * Used to display output. A View object is used to define the kind of output (either a template containing a form,
     * a template without a form or a new, external PHP page), its name and possible parameters. If the output is in a
     * template (types FORM or TEMPLATE) then the parameters supplied with the View object are passed on to the
     * template engine and the template file specified in the View object is displayed. If the output is in another,
     * external PHP file (type URL), the parameters supplied in the View object are converted to a valid query
     * parameter string which is then appended to the defined file name and a HTTP redirect to the assembled URL is
     * initiated.
     * @param View|null $view An optional View object used to display output or null to use the initially supplied
     * view.
     */
    protected function show(View $view = null)
    {
        if (is_null($view)) {
            $view = $this->currentView;
        }
        switch ($view->getType()) {
            case View::FORM:
                foreach ($view->getParameters() as $param) {
                    if ($param instanceof PostParameter) {
                        $this->smarty->assign($param->getName(), $param);
                    } else {
                        if ($param instanceof GenericParameter) {
                            $this->smarty->assign($param->getName(), $param->getValue());
                        }
                    }
                }
                $this->smarty->display($view->getName());
                break;
            case View::TEMPLATE:
                foreach ($view->getParameters() as $param) {
                    if ($param instanceof GenericParameter) {
                        $this->smarty->assign($param->getName(), $param->getValue());
                    }
                }
                $this->smarty->display($view->getName());
                break;
            case View::URL:
                $queryParameters = [];
                foreach ($view->getParameters() as $key => $param) {
                    if ($param instanceof GenericParameter) {
                        $value = $param->getValue();
                        if (is_array($value)) {
                            $queryParameters = array_merge($queryParameters, $value);
                        } else {
                            $queryParameters[$param->getName()] = $value;
                        }
                    } else {
                        if (is_array($param)) {
                            $queryParameters = array_merge($queryParameters, $param);
                        } else {
                            $queryParameters[$key] = $param;
                        }
                    }
                }
                header("Location: " . $view->getName() . "?" . http_build_query($queryParameters));
                break;
            default:
                // Throw an exception or show an error page
                break;
        }
    }

    /**
     * Convenience method to check if a form field is empty, thus contains only an empty string. This is preferred to
     * PHP's own empty() method which also defines inputs such as "0" as empty.
     * @param string $index The index in the superglobal $_POST array.
     * @return bool Returns true if the form field is empty, otherwise false.
     */
    protected function isEmptyPostField(string $index): bool
    {
        return (!isset($_POST[$index]) || strlen(trim($_POST[$index])) === 0);<commit_msg>Added exit after header redirect<commit_after><?php

require_once("View.php");
require_once("GenericParameter.php");
require_once("PostParameter.php");
require_once("vendor/smarty/smarty/libs/Smarty.class.php");

/**
 * The object oriented and template based norm form is used to gather, validate and process form data in a flexible way.
 *
 * This abstract class represents a well known process of gathering, validating and processing form data within a single
 * PHP structure. To use it, simple extend this class and implement the abstract methods isValid() (for validation) and
 * business() for processing/business logic. Then create an object of your subclass, supply a View object and start
 * the process by calling normForm.
 * The initial call will show the form supplied by the View object. Submitted form data will then be validated by your
 * implementation of isValid(). Occurring error messages can be passed on to the View object and displayed in the
 * template output. Once validation is passed, the data entered in the form can be processed in business() in any
 * suitable way. By returning a new View object in business() the processed data can be displayed flexibly (in a new
 * template or in a separate file). If nothing is returned the current (form) view also can be used to show output.
 *
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>@fh-hagen<EMAIL>>
 * @version 2017
 */
abstract class AbstractNormForm
{

    /**
     * @var Smarty $smarty Hold the reference to the Smarty template engine.
     */
    protected $smarty;

    /**
     * @var View $currentView Holds the currently supplied View object that will be used in the template to render
     * output.
     */
    protected $currentView;

    /**
     * @var array $errorMessages An array containing all error messages being set by isValid().
     */
    protected $errorMessages;

    /**
     * @var string $statusMessage An optional status message that can be set in business() when processing data was
     * successful.
     */
    protected $statusMessage;

    /**
     * Abstract method used to validate the form input. Must be implemented in the subclass.
     * @return bool Returns true if validation was successful, otherwise false.
     */
    abstract protected function isValid(): bool;

    /**
     * Abstract method for processing the validated form input (a.k.a. business logic). Must be implemented in the
     * subclass.
     * @return View|null Can return a View object to determine a new target for output or null to keep the same view.
     */
    abstract protected function business();

    /**
     * Creates a new instance for a norm form object and initializes all necessary fields. A View object is used to
     * initially define how and where output is displayed via the template engine and supply parameters to the template.
     * The template engine itself is also set up, two optional parameters allow setting the template paths.
     * @param View $defaultView Holds the initial @View object used for displaying the form.
     * @param string $templateDir Optional parameter for setting the path to the template files.
     * @param string $compileDir Optional parameter for setting the path for compiled templates.
     */
    public function __construct(
        View $defaultView,
        string $templateDir = "templates",
        string $compileDir = "templates_c"
    ) {
        $this->smarty = new Smarty();
        $this->smarty->template_dir = $templateDir;
        $this->smarty->compile_dir = $compileDir;
        $this->currentView = $defaultView;
        $this->errorMessages = [];
        $this->statusMessage = "";
    }

    /**
     * Main "decision" method for the form processing. This decision tree uses isFormSubmission() to check if the form
     * is being initially displayed or shown again after a form submission and either calls show() to display the form
     * (using the supplied View object) or validate the received input in isValid(). If validation failed, show() is
     * called again. Possible error messages provided as parameters to the View object in isValid() can now be
     * displayed. Once the submission was correct, business() is called where the data can be processed as needed. If
     * this method returns a new View object it is used to display the output as specified there, otherwise the current
     * view is kept.
     */
    public function normForm()
    {
        if ($this->isFormSubmission()) {
            if ($this->isValid()) {
                $view = $this->business();
                $this->show($view);
            } else {
                $this->show();
            }
        } else {
            $this->show();
        }
    }

    /**
     * Checks if the current request was an initial one (thus using GET) or a recurring one after a form submission
     * (where POST was used).
     * @return bool Returns true if a form was submitted or false if it was an initial call.
     */
    protected function isFormSubmission(): bool
    {
        return ($_SERVER["REQUEST_METHOD"] === "POST");
    }

    /**
     * Used to display output. A View object is used to define the kind of output (either a template containing a form,
     * a template without a form or a new, external PHP page), its name and possible parameters. If the output is in a
     * template (types FORM or TEMPLATE) then the parameters supplied with the View object are passed on to the
     * template engine and the template file specified in the View object is displayed. If the output is in another,
     * external PHP file (type URL), the parameters supplied in the View object are converted to a valid query
     * parameter string which is then appended to the defined file name and a HTTP redirect to the assembled URL is
     * initiated.
     * @param View|null $view An optional View object used to display output or null to use the initially supplied
     * view.
     */
    protected function show(View $view = null)
    {
        if (is_null($view)) {
            $view = $this->currentView;
        }
        switch ($view->getType()) {
            case View::FORM:
                foreach ($view->getParameters() as $param) {
                    if ($param instanceof PostParameter) {
                        $this->smarty->assign($param->getName(), $param);
                    } else {
                        if ($param instanceof GenericParameter) {
                            $this->smarty->assign($param->getName(), $param->getValue());
                        }
                    }
                }
                $this->smarty->display($view->getName());
                break;
            case View::TEMPLATE:
                foreach ($view->getParameters() as $param) {
                    if ($param instanceof GenericParameter) {
                        $this->smarty->assign($param->getName(), $param->getValue());
                    }
                }
                $this->smarty->display($view->getName());
                break;
            case View::URL:
                $queryParameters = [];
                foreach ($view->getParameters() as $key => $param) {
                    if ($param instanceof GenericParameter) {
                        $value = $param->getValue();
                        if (is_array($value)) {
                            $queryParameters = array_merge($queryParameters, $value);
                        } else {
                            $queryParameters[$param->getName()] = $value;
                        }
                    } else {
                        if (is_array($param)) {
                            $queryParameters = array_merge($queryParameters, $param);
                        } else {
                            $queryParameters[$key] = $param;
                        }
                    }
                }
                header("Location: " . $view->getName() . "?" . http_build_query($queryParameters));
                exit();
                break;
            default:
                // Throw an exception or show an error page
                break;
        }
    }

    /**
     * Convenience method to check if a form field is empty, thus contains only an empty string. This is preferred to
     * PHP's own empty() method which also defines inputs such as "0" as empty.
     * @param string $index The index in the superglobal $_POST array.
     * @return bool Returns true if the form field is empty, otherwise false.
     */
    protected function isEmptyPostField(string $index): bool
    {
        return (!isset($_POST[$index]) || strlen(trim($_POST[$index])) === 0);
{'fraction_non_alphanumeric': 0.08729014019500375, 'fraction_numerical': 0.0006923210061731956, 'mean_word_length': 2.1823021846888193, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 102, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6137206', 'n_tokens_mistral': 4133, 'n_tokens_neox': 3995, 'n_words': 1838}