diff options
Diffstat (limited to 'app/class')
-rw-r--r-- | app/class/database.class.php | 51 | ||||
-rw-r--r-- | app/class/form.class.php | 179 | ||||
-rw-r--r-- | app/class/globals.php | 22 |
3 files changed, 252 insertions, 0 deletions
diff --git a/app/class/database.class.php b/app/class/database.class.php index cdfdfce..3d94e16 100644 --- a/app/class/database.class.php +++ b/app/class/database.class.php @@ -115,6 +115,57 @@ abstract class database return true; } + + /* + * Test and set new database configuration parameters. + * If the given params fail, error's are set and this + * function returns false. On success, parameters are + * written to 'dbconfig.php' and true is returned. + */ + public static function setConfig(string $engine, string $host, + string $uname, string $passwd, string $name) : bool + { + global $_SCROTT; + + /* test configuration */ + $_SCROTT['conf'] = "conf"; + $_SCROTT['dbEngine'] = $engine; + $_SCROTT['dbHost'] = $host; + $_SCROTT['dbUname'] = $uname; + $_SCROTT['dbPasswd'] = $passwd; + $_SCROTT['dbName'] = $name; + + try + { + $db = self::getInstance(); + } + catch (Exception $e) + { + logError(ERROR, $e->getMessage()); + return false; + } + + /* write file */ + $f = fopen(DATABASE_CONFIG_FILE, "w"); + + if (!$f) + { + logError(ERROR, "Can not create configuration file"); + return false; + } + + fwrite($f, "<?php\n"); + fwrite($f, "\$_SCROTT['conf'] = 'conf';\n"); + fwrite($f, "\$_SCROTT['dbEngine'] = '" . $engine . "';\n"); + fwrite($f, "\$_SCROTT['dbHost'] = '" . $host . "';\n"); + fwrite($f, "\$_SCROTT['dbUname'] = '" . $uname . "';\n"); + fwrite($f, "\$_SCROTT['dbPasswd'] = '" . $passwd . "';\n"); + fwrite($f, "\$_SCROTT['dbName'] = '" . $name . "';\n"); + fwrite($f, "?>\n"); + + fclose($f); + return true; + } } ?> diff --git a/app/class/form.class.php b/app/class/form.class.php new file mode 100644 index 0000000..8f9d936 --- /dev/null +++ b/app/class/form.class.php @@ -0,0 +1,179 @@ +<?php + +/* + * SCROTT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * For more information, please refer to UNLICENSE + */ + +/* + * Model web-forms and simplify the process of accepting, validating, and + * sanitizing user input. + */ +class form +{ + /* + * These arrays track the meta-data of all fields defined on this + * form. This mainly includes their type, range (if numeric), and + * whether or not the field is required. + */ + private $textFields = array(); + private $numbFields = array(); + private $enumFields = array(); + + /* + * Add new text field to this form + */ + public function text(string $name, bool $required = true, + string $deflt = "") : void + { + $this->textFields[] = array( + 'name' => $name, + 'required' => $required, + 'default' => $deflt, + ); + } + + /* + * Add new numeric field to this form + */ + public function numeric(string $name, ?int $min = NULL, ?int $max = NULL, + int $deflt = 0, bool $isInt = true, bool $required = true) : void + { + $this->numbFields[] = array( + 'name' => $name, + 'min' => $min, + 'max' => $max, + 'default' => $deflt, + 'isInt' => $isInt, + 'required' => $required, + ); + } + + /* + * Add new enumeration field to this form + */ + public function enum(string $name, array $values, $deflt = NULL, + bool $required = true) : void + { + $this->enumFields[] = array( + 'name' => $name, + 'values' => $values, + 'default' => $deflt, + 'required' => $required, + ); + } + + /* + * Add new boolean field to this form + */ + public function flag(string $name) : void + { + $this->enum($name, array("1", "0"), "0", false); + } + + /* + * Populate this form with input data from web page. If an error + * is encountered, or a required field is missing, false is returned. + */ + public function populate(array $input) : bool + { + /* detect duplicate names */ + $names = array(); + + foreach ($this->textFields as $field) + $names[] = $field['name']; + + foreach ($this->numbFields as $field) + $names[] = $field['name']; + + foreach ($this->enumFields as $field) + $names[] = $field['name']; + + if (count(array_unique($names)) != count($names)) + throw new Exception("Internal error: Duplicate field names defined in form"); + + /* init text fields */ + foreach ($this->textFields as $field) + { + if (isset($input[$field['name']]) && $input[$field['name']] != "") + $this->{$field['name']} = htmlentities($input[$field['name']], ENT_QUOTES); + + else if ($field['required']) + logError(ERROR, $field['name'] . " is required"); + + else + $this->{$field['name']} = $field['default']; + } + + /* init numeric fields */ + foreach ($this->numbFields as $field) + { + if (isset($input[$field['name']]) && $input[$field['name']] != "") + { + if (!is_numeric($input[$field['name']])) + { + logError(ERROR, $field['name'] . " must be numeric"); + continue; + } + + if ($field['isInt'] && (floor($input[$field['name']]) != $input[$field['name']])) + { + logError(ERROR, $field['name'] . " must be an integer"); + continue; + } + + if (!is_null($field['min']) && ($input[$field['name']] < $field['min'])) + { + logError(ERROR, $field['name'] . " must be no less than " . $field['min']); + continue; + } + + if (!is_null($field['max']) && ($input[$field['name']] > $field['max'])) + { + logError(ERROR, $field['name'] . " must be no more than " . $field['max']); + continue; + } + + $this->{$field['name']} = $input[$field['name']]; + } + + else if ($field['required']) + logError(ERROR, $field['name'] . " is required"); + + else + $this->{$field['name']} = $field['default']; + } + + /* init enum fields */ + foreach ($this->enumFields as $field) + { + if (isset($input[$field['name']]) && $input[$field['name']] != "") + { + if (array_search($input[$field['name']], $field['values']) === false) + { + logError(ERROR, $field['name'] . " is not an appropriate value"); + continue; + } + + $this->{$field['name']} = $input[$field['name']]; + } + + else if ($field['required']) + logError(ERROR, $field['name'] . " is required"); + + else + $this->{$field['name']} = $field['default']; + } + + return !isError(ERROR); + } +} + +?> diff --git a/app/class/globals.php b/app/class/globals.php index 615efa6..776fc35 100644 --- a/app/class/globals.php +++ b/app/class/globals.php @@ -77,6 +77,28 @@ function require_https() : void } /* + * Check whether an action string was submitted by the user agent + */ +function isAction(string $action) : bool +{ + if (!isset($_REQUEST['action'])) + return false; + + return $_REQUEST['action'] == $action; +} + +/* + * Get an array of submitted form input + */ +function input() : array +{ + if (!isset($_REQUEST['input'])) + throw new Exception("Requested form input, but no input data was supplied"); + + return $_REQUEST['input']; +} + +/* * Check for errors, warnings, or notices */ function isError(string $level) : bool |