FormEntity.php
<?php
namespace Doc;
class FormEntity extends \Doc\Entity {
protected $propAttribute = 'name';
public function fillSelf($removeAPIData){
$this->addHiddenInput('id','');
$table = $this->table;
$lookup = $this->lookupStr;
$form = $this->node;
$formName = $this->options['formName'] ?? null;
// var_dump($table);
// exit;
// if ($viewName!=null){
// $form->innerHTML = "\n".'<input type="hidden" name="view_name" value="'.$viewName.'"/>'."\n".$form->innerHTML;
// }
// if ($formName!=null){
// $form->innerHTML = "\n".'<input type="hidden" name="form_name" value="'.$formName.'"/>'."\n".$form->innerHTML;
// }
$form->setAttribute('method','POST');
$form->setAttribute('action','/submit_auto_form/');
if ($this->doesHaveFileInput()){
$form->setAttribute('enctype','multipart/form-data');
}
if ($table!=null){
$this->addHiddenInput('autoschema_table',$table);
}
if ($lookup!=null){
// echo "\n\n".$lookup."\n\n";
$this->addHiddenInput('autoschema_lookup',$lookup);
}
if ($formName!=null){
$this->addHiddenInput('autoschema_form',$formName);
}
if ($this->new&&$this->initData!=null){
$this->addHiddenInput('autoschema_initData',$this->initDataStr);
// $data = $this->initData;
// foreach ($data as $key=>$value){
// $this->addHiddenInput($key,$value);
// }
}
if (!$this->new){
parent::fillSelf($removeAPIData);
}
}
public function setFormInputValue($node,$value){
$tagName = strtolower($node->tagName);
$type = strtolower($node->getAttribute('type'));
// echo "\n\n---------".$tagName.':'.$type."\n\n";
// exit;
if ($tagName=='textarea'){
$node->innerHTML = $value;
} else if ($tagName=='input'&&$type=='file'){
// echo "it's a file input";
$attr = $node->getAttribute('name');
$queryStr = "//img[@for='{$attr}']";
$xPath = new \DOMXPath($this->doc);
$holderList = $xPath->query($queryStr);
$fileHolder = $holderList[0]??null;
if(is_object($fileHolder)){
$fileHolder->setAttribute('src',$value);
$attr = $fileHolder->getAttribute($attr);
$fileHolder->removeAttribute($attr);
$fileHolder->setAttribute('data-name',$attr);
}
// exit;
// echo 'fileholder';
// exit;
} else if ($tagName=='input'){
$node->setAttribute('value',$value);
}
return true;
}
public function enableEditMode(){
}
public function submit($submitData){
// var_dump($this->initData);
// exit;
// $this->insertHiddenIdInput($this->node);
$fields = $this->getInputs();
$table = $this->table;
$filesToUpload = [];
foreach ($fields as $index => $data) {
$name = $data['name'];
$required = $data['required'];
$type = $data['type'];
$tag = $data['tag'];
$input = $data['input'];
if ($type=='file'){
$file = $_FILES[$name]?? null;
if ($file==null)$pass=false;
$filesToUpload[] = ['file'=>$_FILES[$name],
'inputData'=>$data
];
unset($_FILES[$name]);
if ($pass)continue;
} else {
$pass = $this->verify($data, $submitData[$name] ?? null);
}
if (!$pass) {
throw new \Exception("Input '{$name}' failed verification");
}
$saveData[$name] = $submitData[$name];
unset($submitData[$name]);
}
if (count($submitData) > 0) {
// print_r($submitData);
throw new \Exception("More data was sent to the server than was requested.");
}
foreach ($this->initData as $key=>$value){
$saveData[$key] = $value;
}
foreach ($filesToUpload as $index=>$data){
$file = $data['file'];
$inputData = $data['inputData'];
// print_r($this->options);
// exit;
$fileName = $this->schemaDoc->uploadFile($file);
if ($fileName===false)continue;
$urlPath = '/'.$this->schemaDoc->imageUrlPrefix.'/'.$fileName;
$urlPath = str_replace(['///','//'],'/',$urlPath);
$saveData[$inputData['name']] = $urlPath;
}
$bean = \RDB::dispense($table);
$bean->import($saveData);
\RDB::store($bean);
}
protected function doesHaveFileInput(){
$form = $this->node;
$x = new \DOMXpath($this->doc);
$inputs = $x->query('//input[@type="file"]');
foreach ($inputs as $input){
$parent = $input;
while ($parent==$parent->parentNode){
if ($parent==$form)return true;
}
}
return false;
}
protected function addHiddenInput($name,$value){
$xPath = new \DOMXpath($this->doc);
$existing = $xPath->query('//input[@type="hidden"][@name="'.$name.'"]', $this->node);
if ($existing->count()>1){
throw new \Exception("There are multiple hidden inputs with the same name");
} else if ($existing->count()==0){
$this->node->innerHTML = "\n".'<input type="hidden" name="'.$name.'" value="'.$value.'"/>'."\n".$this->node->innerHTML;
} else {
$input = $existing->item(0);
$input->value = $value;
}
}
protected function getInputs()
{
$xPath = new \DOMXpath($this->doc);
$htmlInputs = $xPath->query('.//*[@name]',$this->node);
$inputs = [];
foreach ($htmlInputs as $input) {
if ($input->tagName == 'form') {
continue;
}
$prefix = 'autoschema_';
if (substr($input->getAttribute('name'),0,strlen($prefix))==$prefix){
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;
}
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;
}
}