<?php
/*
* SCROTT Copyright (C) 2016 Malf Furious
*
* Scrott is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* Scrott is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*/
/*
* Model web-forms and simplify the process of accepting, validating, and sanitizing input
*/
class Form
{
/*
* Constructor
*/
function __construct()
{
$this->textFields = array();
$this->numbFields = array();
$this->enumFields = array();
$this->errorlist = array();
}
/*
* Log an error
*/
function logError($str)
{
$this->errorlist[] = $str;
}
/*
* Add new text field to the form
*/
function field_text($name, $deflt = null, $req = true)
{
if ($req !== true)
$req = false;
$this->textFields[] = array(
'name' => $name,
'deflt' => $deflt,
'req' => $req
);
}
/*
* Add new numeric field to the form
*/
function field_numeric($name, $min = null, $max = null, $deflt = null, $integer = true, $req = true)
{
if ($req !== true)
$req = false;
if ($integer !== true)
$integer = false;
$this->numbFields[] = array(
'name' => $name,
'min' => $min,
'max' => $max,
'deflt' => $deflt,
'int' => $integer,
'req' => $req
);
}
/*
* Add new enumeration field to the form
*/
function field_enum($name, $values, $deflt = null, $req = true)
{
if ($req !== true)
$req = false;
$this->enumFields[] = array(
'name' => $name,
'vals' => $values,
'deflt' => $deflt,
'req' => $req
);
}
/*
* Add new boolean field to the form
*/
function field_bool($name)
{
$this->field_enum($name, array("1", "0"), "0");
}
/*
* Populate the form with input data from web page
*/
function populate($input)
{
/* detect duplicate names */
$names = array();
foreach ($this->textFields as $fld)
$names[] = $fld['name'];
foreach ($this->numbFields as $fld)
$names[] = $fld['name'];
foreach ($this->enumFields as $fld)
$names[] = $fld['name'];
if (count(array_unique($names)) != count($names))
{
$this->logError("Internal error: Duplicate field names defined in form");
return false;
}
/* init text fields */
foreach ($this->textFields as $fld)
{
if (isset($input[$fld['name']]) && $input[$fld['name']] != "")
$this->{$fld['name']} = htmlEntities($input[$fld['name']], ENT_QUOTES);
else if (!is_null($fld['deflt']))
$this->{$fld['name']} = $fld['deflt'];
else if ($fld['req'])
$this->logError($fld['name'] . " is required");
}
/* init numeric fields */
foreach ($this->numbFields as $fld)
{
if (isset($input[$fld['name']]) && $input[$fld['name']] != "")
{
if (!is_numeric($input[$fld['name']]))
{
$this->logError($fld['name'] . " must be numeric");
continue;
}
if ($fld['int'] && (floor($input[$fld['name']]) != $input[$fld['name']]))
{
$this->logError($fld['name'] . " must be an integer");
continue;
}
if (!is_null($fld['min']) && ($input[$fld['name']] < $fld['min']))
{
$this->logError($fld['name'] . " must be no less than " . $fld['min']);
continue;
}
if (!is_null($fld['max']) && ($input[$fld['name']] > $fld['max']))
{
$this->logError($fld['name'] . " must be no more than " . $fld['max']);
continue;
}
$this->{$fld['name']} = $input[$fld['name']];
}
else if (!is_null($fld['deflt']))
$this->{$fld['name']} = $fld['deflt'];
else if ($fld['req'])
$this->logError($fld['name'] . " is required");
}
/* init enum fields */
foreach ($this->enumFields as $fld)
{
if (isset($input[$fld['name']]) && $input[$fld['name']] != "")
{
if (array_search($input[$fld['name']], $fld['vals']) === false)
{
$this->logError($fld['name'] . " is not an appropriate value");
continue;
}
$this->{$fld['name']} = $input[$fld['name']];
}
else if (!is_null($fld['deflt']))
$this->{$fld['name']} = $fld['deflt'];
else if ($fld['req'])
$this->logError($fld['name'] . " is required");
}
/* return */
return count($this->errorlist) == 0;
}
/*
* Handle an uploaded file
*/
function saveFile($file, $maxsize, $allowed_mime, $path, $req = false)
{
if (isset($file) && !is_null($file))
{
if ($file['error'] > 0)
{
if ($file['error'] != UPLOAD_ERR_NO_FILE)
$this->logError("An unknown error occurred");
return false;
}
if ($file['size'] > $maxsize)
{
$this->logError("File must be no larger than " . $maxsize . " bytes");
return false;
}
if (is_array($allowed_mime) && array_search($file['type'], $allowed_mime) === false)
{
$this->logError("File type is not supported");
return false;
}
if (!move_uploaded_file($file['tmp_name'], $path))
{
$this->logError("Error saving uploaded file");
return false;
}
}
else if ($req)
{
$this->logError("File upload is required");
return false;
}
return true;
}
}
?>