Ok cette méthode fonctionne, mais chaque fois que vous envoyez dans une symfony demande édifie toute la forme, donc je créé une classe abstraite entre la classe de formulaire et la classe sous forme de base:
abstract class wsExtensionForm extends BaseForm {
protected $widgetClass = 'input-widget';
public function configure() {
$user = sfContext::getInstance()->getUser();
$ftw = $user->hasAttribute('fieldToValidate') ? $user->getAttribute('fieldToValidate') : false;
if ($ftw) {
$this->generateValidator($ftw, $this->validatorsConfig[$ftw]);
$user->getAttributeHolder()->remove('fieldToValidate');
} else {
$this->generateWidgets($this->widgetsConfig, $this->widgetClass);
$this->generateValidators($this->validatorsConfig);
$this->generateLabels($this->labelsConfig);
}
}
protected function generateWidget($wConfig) {
}
protected function generateValidator($id, $vConfig) {
if (!is_array($vConfig)){
if ($vConfig == 'sfValidatorChoice') {
$methodName = 'get'.ucfirst($id).'Choices';
$this->validatorSchema[$id] = new $vConfig(array('choices' => array_keys($this->$methodName()), 'multiple' => false), array());
} else {
$this->validatorSchema[$id] = new $vConfig();
}
}
}
protected function generateHelp($hConfig) {
}
protected function generateWidgets($wsConfig, $class) {
foreach($wsConfig as $id => $widget) {
if (!is_array($widget)) {
if ($widget == 'sfWidgetFormInputText') {
$this->widgetSchema[$id] = new $widget(array(), array('class' => $class));
} elseif($widget == 'sfWidgetFormChoice') {
$methodName = 'get'.ucfirst($id).'Choices';
$this->widgetSchema[$id] = new $widget(array('choices' => $this->$methodName(), 'multiple' => false, 'expanded' => false), array('class' => $class));
}
}
}
}
protected function generateValidators($vsConfig) {
foreach ($vsConfig as $id => $validator) {
if (!is_array($validator)){
if ($validator == 'sfValidatorChoice') {
$methodName = 'get'.ucfirst($id).'Choices';
$this->validatorSchema[$id] = new $validator(array('choices' => array_keys($this->$methodName()), 'multiple' => false), array());
} else {
$this->validatorSchema[$id] = new $validator();
}
}
}
}
protected function generateLabels($lsConfig) {
$this->widgetSchema->setLabels($lsConfig);
}
protected function generateHelps($hsConfig) {
}
}
Après cela, vous peut le faire dans votre contrôleur:
public function executeProc(sfWebRequest $request) {
// checking if request parameters are OK
$this->initAction($request->getParameter('form_category'), $request->getParameter('form_id'));
if ($request->isXmlHttpRequest()) {
$field = $request->getParameter('field');
$field = explode('_', $field);
$field = array_reverse($field);
$field = $field[0];
$fieldValue = $request->getParameter('fieldValue');
$this->getUser()->setAttribute('fieldToValidate', $field);
$this->form = new $this->formName();
$vs = $this->form->getValidatorSchema();
try {
$toValidate = $vs[$field]->clean($fieldValue);
} catch (sfValidatorError $e) {
return $this->renderText($e->getMessage());
}
return $this->renderText('ok');
} else {
$this->form = new $this->formName();
if ($request->isMethod('post')) {
$this->form->bind($request->getParameter($this->nameFormat));
if ($this->form->isValid()) {
exit('valid');
}
} else {
$this->forward404();
}
$this->form->getWidgetSchema()->setNameFormat($this->nameFormat.'[%s]');
$this->setTemplate('show');
}
}
et symfony ne génère pas la forme entière de sorte que vous pouvez enregistrer des cpu.
Cela me semble être une bonne solution, d'autant plus que vous utilisez DRY-ly avec les validateurs déjà définis dans symfony. – yitznewton