<?php
namespace Fresh;
class Form extends View {
public function initialize(){
$this->addQuery('//form',[$this,'handleForm']);
$this->addCompileHandler('form-input',[$this,'handleFormInput']);
// $this->addRuntimeHandler('find',[$this,'find']);
// $this->setRuntimeHandler('formatObjectValue',[$this,'formatObjectValue']);
// $this->addFormatter('markdown',[$this,'mdToHtml']);
}
protected function fileFor($viewName){
$viewName .= 'Form';
$file = $this->component->dir.'/view/'.$viewName.'.php';
return $file;
}
protected function compileFileFor($viewName){
$viewName .= 'Form';
return $this->component->dir.'/compiled/'.$viewName.'.php';
}
protected function handleFormInput($compiler,$inputNode,$table){
$varName = $table;
$propName = $inputNode->getAttribute('name');
$placeholder = $compiler->placeholderFor('<?=$'.$varName.'->'.$propName.'; ?>');
if (strtolower($inputNode->getAttribute('type'))=='file'){
$form = $inputNode->form;
$form->enctype = "multipart/form-data";
} else if (strtolower($inputNode->getAttribute('type'))=='checkbox'){
$placeholder = $compiler->placeholderFor('<?=((bool)$'.$varName.'->'.$propName.') ? " checked" : ""; ?>');
$inputNode->setAttribute($placeholder,'');
// $inputNode->setAttribute('checked','should this be?');
} else if (strtolower($inputNode->tagName)=='textarea'){
$inputNode->innerHTML = $placeholder;
} else if (strtolower($inputNode->tagName)=='input'){
$inputNode->setAttribute('value',$placeholder);
} else if (strtolower($inputNode->tagName)=='img'){
$inputNode->src = $placeholder;
}
}
protected function handleForm(\Taeluf\PHTML $doc, \Fresh\Form $form, \Taeluf\PHTML\Compiler $compiler, \Taeluf\PHTML\Node $node){
//cleanse the form of php
//load the view which this form relates to
// get the list of entities from the view
// get the first entity
// get the table
// set input values & innertexts to print the database value
// output the compiled form
// Add "smarter" value-setting for input types like select or textarea
// Add enctype (if file input found),method,action to form
// compile an id-based lookup for that table
$placeholder = $compiler->placeholderFor($node);
$node->parentNode->replaceChild($doc->createTextNode($placeholder),$node);
$node->addHiddenInput('id','');
$view = $this->view();
$entities = $view->getEntities();
$entity = $entities[0] ?? null;
if ($entity==null)throw new \Exception("We could not find a view for this form named '{$form->name}'");
foreach ($this->handler->compile->form??[] as $handler){
$handler($form,$doc,$compiler,$node);
}
// var_dump($routes);
// exit;
$table = $entity->getAttribute('rb-table');
// $lookup = 'id:<?=$id? >';
$varName = $table;
$inputNodes = $doc->xpath('.//*[@name]',$node);
foreach ($inputNodes as $input){
$this->executeCompileHandlers('form-input',$compiler,$input,$table);
}
$node->action = $compiler->placeholderFor("<?=\$submit_url;?>");
$node->method = 'POST';
$node->addHiddenInput('fresh_table',$table);
$escTable = var_export($table,true);
/**
* Call `$compo->addCompileHandler('Form.EntityLoop.Start', $callable)`
* `$callable` should:
* - Accept NO paramaters
* - Return a string of valid PHP code
* - DO NOT include open & close tags @ beginning and end of your code.
* - You MAY close & re-open amidst your code.
*
* @TODO Maybe pass some paramaters to the callable???
*
* @export(Handler.Compile.Form_Entity_Loop_Start)
*/
$loopStartCode = $this->executeCompileHandlers('Form.EntityLoop.Start');
$formLoopStartCode = implode("\n",$loopStartCode);
$phpOpen =
<<<PHP
<?php
\$table = {$escTable};
\$find = 'id:'.\$id.';';
\$list = \$this->callHandler('find',\$table,\$find);
foreach (\$list as \$rb_object){
\${$varName} = \$rb_object;
{$formLoopStartCode}
?>
PHP;
$compiler->placeholderPrepend($placeholder,$phpOpen);
$phpClose =
<<<PHP
<?php
}
?>
PHP;
$compiler->placeholderAppend($placeholder,$phpClose);
return;
}
/**
* Get an array of elements which are:
* 1. child of a <form> tag
* 2. Have a name attribute
* 3. NOT a <form> tag itself
*
* @return an array of elements or an empty array if none found
*/
public function getInputs(){
$compiler = new \Taeluf\PHTML\Compiler();
$dirtySource = file_get_contents($this->file);
$cleanSource = $compiler->cleanSource($dirtySource);
$preDocHandlers = $this->handler->compile->preDoc ?? [];
foreach ($preDocHandlers as $handler){
$cleanSource = $handler($cleanSource,$dirtySource,$compiler,$this);
}
$doc = new \Taeluf\PHTML($cleanSource);
$inputs = $doc->xpath('//form//*[@name]');
$list=[];
foreach ($inputs as $i)if (strtolower($i->tagName)!='form')$list[] = $i;
return $list;
}
}