freenet-router |
Subversion Repositories: |
Compare with Previous - Blame - Download
<?php
namespace Phem\Libraries\Forms;
use Srovnavac\Libraries\Environment\EnvironmentManager;
use Doctrine\Common\Annotations\AnnotationReader;
use Phem\Core\Collection;
use Phem\Core\CollectionSortType;
use Phem\Libraries\Forms\Annotations\Form as AnnotationForm;
use Phem\Libraries\Forms\Model\Form;
use Phem\Libraries\Forms\Model\FormField;
use Phem\Libraries\Forms\Model\FormGroup;
use ReflectionClass;
use ReflectionProperty;
/**
* @author kubapet
*/
class AnnotationFormBuilder
{
private $readOnlyAll = false;
private $version = 0;
private $basePrefix = "Phem_";
public function buildForm($className, $object = null, $form = null, $form_id = null, $prefix = 'Phem_')
{
$form = $this->recursionBuildForm($className, $object, $form, $prefix);
/* insert form_id */
$formIdField = new FormField();
$formIdField->setName($prefix . "version");
$formIdField->setValue($this->version);
$formIdField->setType("hidden");
$form->getGroups()->get($form->getDefaultGroup())->getFields()->add($formIdField);
$form->getGroups()->sort(CollectionSortType::NUMERIC | CollectionSortType::ASC | CollectionSortType::VALUE, "Order");
foreach ($form->getGroups() as $group)
{
$group->getFields()->sort(CollectionSortType::NUMERIC | CollectionSortType::ASC | CollectionSortType::VALUE, "Order");
}
return $form;
}
private function recursionBuildForm($className, $object = null, $form = null, $prefix = 'Phem_')
{
$r = new ReflectionClass($className);
$annotationReader = new AnnotationReader();
$classAnnotations = $annotationReader->getClassAnnotations($r);
if ($form == null)
{
$groups = new Collection();
}
else
$groups = $form->getGroups();
$formSourceField = null;
if ($form == null)
{
$formSourceField = new FormField();
$formSourceField->setName('form_source');
$formSourceField->setValue($className);
$formSourceField->setType("hidden");
}
$hasFormAnnotation = false;
foreach ($classAnnotations as $ca)
{
if ($ca instanceof AnnotationForm)
{
$hasFormAnnotation = true;
if ($form == null)
{
$form = new Form();
$form->setCriticalFields(new Collection());
$form->setAction($ca->action == null ? null : EnvironmentManager::getLinkBuilder()->link($ca->action));
$form->setName($ca->name);
$form->setMethod($ca->method);
$form->setDefaultGroup($ca->defaultGroup);
$form->setAjax($ca->ajax);
$form->setSubmittedButton($ca->submittedButton);
$form->setGroups($groups);
}
elseif ($ca->defaultGroup != null)
$form->setDefaultGroup($ca->defaultGroup);
}
elseif ($ca instanceof Annotations\Group)
{
$group = new FormGroup();
$group->setEnabled($ca->enabled);
$group->setOrder($ca->order);
$group->setShow($object == null ? true : false);
$group->setDefaultOpen($ca->defaultOpen);
$group->setFields(new Collection());
if ($ca->localGroupScope && $prefix != $this->basePrefix)
{
$parentGroup = $groups->get($form->getDefaultGroup());
$group->setCaption($parentGroup->getCaption() . ":" . $ca->caption);
$groups->put($form->getDefaultGroup() . "_" . $ca->name, $group);
}
else
{
$group->setCaption($ca->caption);
$groups->put($ca->name, $group);
}
}
}
/* check and validate class annotations */
/* @var $formAnotation AnnotationForm */
if (!$hasFormAnnotation)
{
return;
}
$properties = $r->getProperties();
$fields = array();
foreach ($properties as $prop)
{
/* @var $prop ReflectionProperty */
$getMethod = "get" . ucFirst($prop->name);
if (!method_exists($className, $getMethod))
{
throw new FormBuilderException(
"FormBuilder: Missing get method for property "
. $prop->name . " of class "
. $className
);
}
//echo "className: ".$className;
$fields[$prop->name] = (method_exists($object, $getMethod) ? $object->$getMethod() : null);
}
if ($groups->isEmpty())
{
$group = new FormGroup();
$group->setCaption($className);
$group->setEnabled(1);
$group->setOrder(1);
$group->setShow(true);
$group->setFields(new Collection());
$groups->put("default", $group);
$form->setDefaultGroup("default");
}
if ($prefix == $this->basePrefix)
if ($groups->containsKey($form->getDefaultGroup()))
$groups->get($form->getDefaultGroup())->getFields()->add($formSourceField);
else
throw new FormBuilderException(
"FormBuilder: defaultGroup '" . $form->getDefaultGroup() . "' does not exist in $className"
);
/*
* Iterate over fields
* and process them according to their annotations
*/
$childs = array();
foreach ($fields as $fieldName => $fieldValue)
{
$formField = null;
$annotations = $annotationReader->getPropertyAnnotations($r->getProperty($fieldName));
$generatedValue = false;
$fieldEnabled = true;
$selectedGroup = $form->getDefaultGroup();
foreach ($annotations as $annotation)
{
if ($annotation instanceof Annotations\Input)
{
/*if ($this->version != 0 && empty($annotation->formVersion))
{
if (!in_array($this->version, $annotation->formVersion))
continue;
}*/
/* @var $annotation Annotations\Input */
$formField = new FormField();
$caption = ($annotation->caption != null ? $annotation->caption : $fieldName);
$formField->setCaption(($annotation->required == false ? $caption : '* ' . $caption));
$formField->setName($prefix . $fieldName);
$formField->setEnabled($annotation->enabled);
$formField->setOrder($annotation->order);
$formField->setReadOnly($annotation->readOnly);
$formField->setValue($fieldValue);
switch ($annotation->type)
{
case "password":
$formField->setType('text');
$formField->setRequired($annotation->required);
break;
case "text":
$formField->setType('text');
$formField->setRequired($annotation->required);
break;
case "file":
$formField->setType('file');
$formField->setRequired($annotation->required);
break;
case "date":
$formField->setType('date');
$formField->setValue($fieldValue instanceof \DateTime ? $fieldValue->format("d.m.Y H:i:s") : null);
$formField->setRequired($annotation->required);
break;
case "checkbox":
$formField->setType('checkbox');
$formField->setRequired($annotation->required);
break;
case "hidden":
$formField->setType('hidden');
break;
}
}
elseif ($annotation instanceof Annotations\Select)
{
$formField = new FormField();
$formField->setCaption(($annotation->caption != null ? $annotation->caption : $fieldName));
if ($annotation->required)
$formField->setCaption('* ' . $formField->getCaption());
$formField->setName($prefix . $fieldName);
$formField->setType("select");
$formField->setOrder($annotation->order);
$formField->setEnabled($annotation->enabled);
$formField->setValue($fieldValue);
$formField->setRequired($annotation->required);
$getMethod = $annotation->options;
if (!method_exists($className, $getMethod))
{
throw new FormBuilderException(
"FormBuilder: Missing get method " .
$getMethod . "() of class "
. get_class($object)
);
}
$formField->setOptions($className::$getMethod($object));
}
elseif ($annotation instanceof Annotations\Textarea)
{
$formField = new FormField();
$formField->setCaption(($annotation->caption != null ? $annotation->caption : $fieldName));
$formField->setName($prefix . $fieldName);
$formField->setType("textarea");
$formField->setOrder($annotation->order);
$formField->setEnabled($annotation->enabled);
$formField->setValue($fieldValue);
$formField->setRequired($annotation->required);
}
elseif ($annotation instanceof Annotations\GeneratedValue)
{
$generatedValue = true;
}
elseif ($annotation instanceof Annotations\AssignToGroup)
{
if ($annotation->localGroupScope)
{
$selectedGroup = $form->getDefaultGroup() . "_" . $annotation->name;
}
else
{
$selectedGroup = $annotation->name;
}
}
elseif ($annotation instanceof Annotations\Relation)
{
$getMethod = "get" . ucFirst($fieldName);
if (!method_exists($className, $getMethod))
{
throw new FormBuilderException(
"FormBuilder: Missing get method " .
$getMethod . "() of class "
. $className
);
}
$child = null;
if (isset($object))
$child = $object->$getMethod();
$childs[] = array("source" => $annotation->source, "child" => $child, "prefix" => $prefix . $fieldName . "_", "assignToGroup" => $selectedGroup);
}
elseif ($annotation instanceof Annotations\Condition)
{
switch ($annotation->matchType)
{
case "EQ":
$form->getCriticalFields()->put($prefix . $annotation->sourceField, "criticalField");
if ($fields[$annotation->sourceField] == $annotation->triggerValue)
{
if (!isset($formField))
continue;
if ($annotation->action == "disable")
{
$formField->setEnabled(false);
}
else
{
$formField->setEnabled(true);
}
}
break;
case "IN":
$form->getCriticalFields()->put($prefix . $annotation->sourceField, "criticalField");
if (in_array($fields[$annotation->sourceField], $annotation->triggerValue))
{
if (!isset($formField))
continue;
if ($annotation->action == "disable")
{
$formField->setEnabled(false);
}
else
{
$formField->setEnabled(true);
}
}
break;
}
}
}
if ($generatedValue && isset($formField))
{
if ($formField->getValue() == null)
$formField->setEnabled(false);
else
$formField->setReadOnly(true);
}
if ($formField != null && $formField->getEnabled() == true)
{
if (!$groups->containsKey($selectedGroup))
{
throw new FormBuilderException(
"FormBuilder: Missing group " .
$selectedGroup . " in FormField " . $formField->getName()
);
}
if ($this->readOnlyAll)
$formField->setReadOnly(true);
if ($formField->getValue() != null && $groups->get($selectedGroup)->getDefaultOpen() == true)
$groups->get($selectedGroup)->setShow(true);
$groups->get($selectedGroup)->getFields()->add($formField);
}
}
foreach ($childs as $child)
{
$form->setDefaultGroup($child["assignToGroup"]);
$a = $this->buildForm($child["source"], $child["child"], $form, $child["prefix"]);
}
return $form;
}
public function getReadOnlyAll()
{
return $this->readOnlyAll;
}
public function setReadOnlyAll($readOnlyAll)
{
$this->readOnlyAll = $readOnlyAll;
}
public function getVersion()
{
return $this->version;
}
public function setVersion($version)
{
$this->version = $version;
}
}