FormToolsWithValidation.php
<?php
class FormToolsWithValidation
{
protected $html = '';
protected $doc;
protected $html = '';
protected $doc;
public function __construct($formHtml,$hideXmlErrors=true)
{
$this->html = $formHtml;
libxml_use_internal_errors($hideXmlErrors);
$domDoc = new \DomDocument();
$domDoc->registerNodeClass('DOMElement', 'JSLikeHTMLElement');
$domDoc->loadHtml($formHtml);
libxml_use_internal_errors(false);
$this->doc = $domDoc;
}
public function getValidSubmissions($userSubmissions,$ignore=[]){
$inputs = $this->getInputs();
$validSubmissions = [];
foreach ($ignore as $index=>$ignoreKey){
unset($userSubmissions[$ignoreKey]);
}
foreach ($inputs as $index=>$inputData){
extract($inputData);
$pass = $this->verify($inputData,$userSubmissions[$name]??null);
if (!$pass){
throw new \Exception("Input '{$name}' failed verification");
}
$validSubmissions[$name] = $userSubmissions[$name];
unset($userSubmissions[$name]);
}
if (count($userSubmissions)>0){
throw new \Exception("More data was sent to the server than was requested.");
}
return $validSubmissions;
}
protected function verify($inputData, $value)
{
//see $this->getInputs() to see what is extracted
extract($inputData);
if (empty($value) && $required) {
return false;
}
if ($type == 'phone') {
$clean = preg_replace('/[^0-9]/', '', $value);
if (strlen($clean) == 10
|| strlen($clean) == 11) {
return true;
}
return false;
}
if ($type == 'text') {
return true;
}
if ($type == 'email') {
$email = filter_var($value, FILTER_VALIDATE_EMAIL);
if ($email === false) {
return false;
}
return true;
}
return true;
}
public function getInputs()
{
$xPath = new DOMXpath($this->doc);
$htmlInputs = $xPath->query('//*[@name]');
$inputs = [];
foreach ($htmlInputs as $input) {
if ($input->tagName == 'form') {
continue;
}
$data = [];
$data['name'] = $input->getAttribute('name');
$data['required'] = $input->hasAttribute('required');
$data['type'] = $input->getAttribute('type');
$data['tag'] = $input->tagName;
$data['input'] = $input;
if (isset($inputs[$data['name']])) {
throw new \Exception("Input '" . $data['name'] . "' occurs twice on the form, which FormTools doesn't know how to handle.");
}
$inputs[$data['name']] = $data;
continue;
}
return $inputs;
}
public function getFormName()
{
$forms = $this->doc->getElementsByTagName('form');
if ($forms->count() > 1) {
throw new \Exception("There are two forms... Form name cannot be retrieved.");
} else if ($forms->count() == 0) {
throw new \Exception("There are no forms. Cannot get form name.");
}
$name = $forms->item(0)->getAttribute('name');
if ($name == null) {
$name = null;
}
return $name;
}
public function insertPlaceholders($placeholders)
{
$xPath = new DOMXpath($this->doc);
$htmlInputs = $xPath->query('//*[@name]');
$formName = $this->getFormName();
foreach ($htmlInputs as $input) {
if ($input->tagName == 'form') {
// $input->getAttribute('name');
continue;
}
$name = $input->getAttribute('name');
$ph = $placeholders[$name] ?? null;
// var_dump($name,$ph);
if ($ph === null) {
continue;
}
$input->setAttribute('placeholder', $ph);
}
}
public function nodeInnerHtml($node){
$innerHTML = '';
$children = $node->childNodes;
foreach ($children as $child) {
$innerHTML .= $child->ownerDocument->saveXML( $child );
}
return $innerHTML;
}
public function innerBodyHTML(){
// this was in my old FormsPlus code...
$output = $this->doc->saveHtml($this->doc->childNodes[1]->childNodes[0]);
$output = substr($output,strlen('<body>'),-strlen('</body>'));
return $output;
}
public function __toString()
{
return $this->doc->saveHtml();
}
public function setFormInputValue($node,$value){
$tagName = strtolower($node->tagName);
$type = strtolower($node->getAttribute('type'));
if ($tagName=='textarea'){
$node->innerHTML = $value;
} else if ($tagName=='input'){
$node->setAttribute('value',$value);
}
return true;
}
public static function uploadFile($file, $destinationFolder, $validExts = ['jpg', 'png'], $maxMB = 15)
{
if (!is_array($file) || $file == []
|| $file['size'] == 0
|| $file['name'] == ''
|| $file['tmp_name'] == ''
|| !is_int($file['error'])) {
return false;
}
try {
if (!isset($file['error']) ||
is_array($file['error'])
) {
throw new RuntimeException('Invalid parameters.');
}
switch ($file['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
throw new RuntimeException('No file sent.');
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
throw new RuntimeException('Exceeded filesize limit.');
default:
throw new RuntimeException('Unknown errors.');
}
// You should also check filesize here.
if ($file['size'] > ($maxMB * 1024 * 1024)) {
throw new RuntimeException('Exceeded filesize limit.');
}
$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
if (!in_array($ext, $validExts)) {
// var_dump($ext);
// var_dump($validExts);
// var_dump($file);
// exit;
throw new RuntimeException('Invalid file format.');
}
if (!file_exists($destinationFolder)) {
mkdir($destinationFolder, 0775, true);
}
$fileName = sha1_file($file['tmp_name']) . '.' . $ext;
if (!move_uploaded_file(
$file['tmp_name'],
$destinationFolder . '/' . $fileName
)
) {
throw new RuntimeException('Failed to move uploaded file.');
}
return $fileName;
} catch (RuntimeException $e) {
throw $e;
}
}
}