OldFormToolsWithRDB.php

<?php

class OldFormToolsWithRDB
{
    protected $html = '';
    protected $data = [];
    protected $editedHtml = '';
    public function __construct($formHtml='',$submitData=[]){
        $this->html = $formHtml;
        $this->editedHtml = $formHtml;
        $this->data = $submitData;
    }
    public function submissions($fields=null){
        if ($fields==null)$fields = $this->getFormFields($this->html);
        $postData = $this->data;
        foreach ($fields as $index=>$data){
            extract($data);
            $pass = $this->verify($data,$postData[$name]??null);
            if (!$pass){
                throw new \Exception("Input '{$name}' failed verification");
            }
            $saveData[$name] = $postData[$name];
            unset($postData[$name]);
        }
        if (count($postData)>0){
            throw new \Exception("More data was sent to the server than was requested.");
        }
        return $saveData;
    }
    public function cleanFields(){
        $formHtml = $this->html;
        $postData = $this->data;
        $fields = $this->getFormFields($formHtml);
        $this->submissions();
        return $fields;
    }
    public function submit($postData, $formHtml){
        $fields = $this->getFormFields($formHtml);
        $formName = $this->getFormName($formHtml);

        foreach ($fields as $index=>$data){
            extract($data);
            $pass = $this->verify($data,$postData[$name]??null);
            if (!$pass){
                throw new \Exception("Input '{$name}' failed verification");
            }
            $saveData[$name] = $postData[$name];
            unset($postData[$name]);
        }
        if (count($postData)>0){
            throw new \Exception("More data was sent to the server than was requested.");
        }
        $bean = \RDB::dispense($formName);
        $bean->import($saveData);
        \RDB::store($bean);
    }
    protected function verify($info, $value){
        extract($info);
        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 getFormFields($formHtml){
        libxml_use_internal_errors(TRUE);
        $domDoc = new \DomDocument();
        $domDoc->loadHtml($formHtml);
        libxml_use_internal_errors(FALSE);
        $xPath = new DOMXpath($domDoc);
        $inputs = $xPath->query('//*[@name]');
        $fields = [];
        foreach ($inputs as $input){
            if ($input->tagName=='form')continue;
            $data = [];
            // $data['input'] = $input;
            $data['name'] = $input->getAttribute('name');
            $data['required'] = $input->hasAttribute('required');
            $data['type'] = $input->getAttribute('type');
            $data['tag'] = $input->tagName;
            if (isset($fields[$data['name']])){
                throw new \Exception("Input '".$data['name']."' occurs twice on the form, which FormTools doesn't know how to handle.");
            }
            $fields[$data['name']] = $data;
            continue;
        }
        return $fields;
    }
    public function getFormName($formHtml){
        $domDoc = new \DomDocument();
        $domDoc->loadHtml($formHtml);
        $xPath = new DOMXpath($domDoc);
        $inputs = $xPath->query('//*[@name]');
        $fields = [];
        foreach ($inputs as $input){
            if ($input->tagName=='form')return $input->getAttribute('name');
        }
        return $fields;
    }

    public function edit($formHtml){
        $domDoc = new \DomDocument();
        $domDoc->loadHtml($formHtml);
        $xPath = new DOMXpath($domDoc);
        $inputs = $xPath->query('//*[@name]');
        $fields = [];
        $formName = $this->getFormName($formHtml);
        $bean = \RDB::findOne($formName,'id = ?',[$_GET['id']??null]);
        if ($bean==null)$bean = \RDB::dispense($formName);
        foreach ($inputs as $input){
            if ($input->tagName=='form'){
                // $input->getAttribute('name');
                continue;
            }
            $name = $input->getAttribute('name');
            $value = $bean->$name ?? null;
            if ($value!==null)$input->setAttribute('value',$value);
        }
        return $domDoc->saveHTML();
    }

    // static public function getFormFields($formHtml){
    //     $domDoc = new \DomDocument();
    //     $domDoc->loadHtml($formHtml);
    //     $xPath = new DOMXpath($domDoc);
    //     $inputs = $xPath->query('//*[@name]');
    //     $fields = [];
    //     foreach ($inputs as $input){
    //         $attr = $input->getAttribute('name');
    //         $fields[$attr] = ($fields[$attr] ?? 0) + 1;
    //         continue;
    //     }
    //     return $fields;
    // }

    static public 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;

        }
    }

    public function insertPlaceholders($placeholders){
        $formHtml = $this->editedHtml;
        $domDoc = new \DomDocument();
        libxml_use_internal_errors(true);
        $domDoc->loadHtml($formHtml);
        libxml_clear_errors();
        $xPath = new DOMXpath($domDoc);
        $inputs = $xPath->query('//*[@name]');
        $fields = [];
        $formName = $this->getFormName($formHtml);
        foreach ($inputs 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);
        }
        $this->editedHtml = $domDoc->saveHtml();
        // exit;
        return $this->editedHtml;
    }

    public function finalHtml(){
        return $this->editedHtml;
    }

    public function __toString(){
        return $this->finalHtml();
    }
}