Kye Etherton
unread,Apr 15, 2012, 9:38:14 AM4/15/12Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to diem-users
Hi all, I have a three tiered form for answering survey questions.
Basically it works by having 'pages' which contain questions. For each
question it makes an 'answer' form, and the answer then embedded
another form depending on the question type.
After working on it for several days now and slowly reducing the
amount of bugs (embedded forms are evil) I now have a problem where
the answers form seams to have data in it at the actions.class.php
level, but not when it tries to save.
Survey section form - embeddeds one answer form per question
<code class="php"><pre>abstract class PluginSurveySectionForm extends
BaseSurveySectionForm {
public function setup() {
parent::setup();
$subForm = new sfForm();
foreach ($this->object->getSurveyQuestion() as $surveyQuestion) {
$answer = Doctrine_Core::getTable('SurveyAnswer')-
>createQuery('s')
->where('s.question = ?', $surveyQuestion->get('id'))
->andWhere('s.dmuser = ?', sfContext::getInstance()-
>getUser()->getDmUser())
->fetchOne();
$form = new SurveyAnswerForm($answer, array('survey_question' =>
$surveyQuestion));
$subForm->embedForm($surveyQuestion, $form);
}
unset($this['title']);
$this->embedForm('Questions', $subForm);
}
protected function doSave($con = null)
{
if (null === $con) {
$con = $this->getConnection();
}
$this->saveEmbeddedForms($con);
}
public function saveEmbeddedForms($con = null, $forms = null) {
if (null === $forms) {
$Questions = $this->getValue('Questions');
$forms = $this->embeddedForms;
foreach ($this->embeddedForms['Questions'] as $name => $form) {
if (!isset($Questions[$name])) {
unset($forms['Questions'][$name]);
}else if(!isset($Questions[$name])){
}
}
}
return parent::saveEmbeddedForms($con, $forms);
}
}</pre></code>
Answer form - embeddeds an answer form depending on the type of
question and sets default values
<code class="php"><pre>abstract class PluginSurveyAnswerForm extends
BaseSurveyAnswerForm {
public function setup() {
parent::setup();
$type = $this->getValue('type');
if (is_null($type)) {
if (!$SurveyQuestion = $this->getOption('survey_question')) {
throw new InvalidArgumentException('You must provide a
question object.');
} else {
$type = $SurveyQuestion->get('type');
$this->setDefault('type', $type);
$this->setDefault('question', $SurveyQuestion->get('id'));
$this->setDefault('dmuser', sfContext::getInstance()-
>getUser()->getDmUser()->get('id'));
}
}
$this->widgetSchema['type'] = new sfWidgetFormInputHidden();
$this->widgetSchema['question'] = new sfWidgetFormInputHidden();
$this->widgetSchema['dmuser'] = new sfWidgetFormInputHidden();
$this->setValidators(array(
'id' => new sfValidatorChoice(array('choices' =>
array($this->getObject()->get('id')), 'empty_value' => $this-
>getObject()->get('id'), 'required' => false)),
'type' => new sfValidatorChoice(array('choices' => array(0 =>
'Integer', 1 => 'String', 2 => 'Float', 3 => 'Text', 4 => 'Boolean', 5
=> 'Files'), 'required' => false)),
'question' => new sfValidatorDoctrineChoice(array('multiple' =>
false, 'model' => 'SurveyQuestion', 'required' => false)),
'dmuser' => new sfValidatorDoctrineChoice(array('multiple' =>
false, 'model' => 'dmUser', 'required' => false)),
));
switch ($type) {
case "Integer":
$this->embedForm('result', new SurveyIntegerForm());
$this->validatorSchema['result']['value'] = new
sfValidatorInteger(array('required' => false));
break;
case "String":
$this->embedForm('result', new SurveyStringForm());
$this->validatorSchema['result']['value'] = new
sfValidatorString(array('required' => false));
break;
case "Float":
$this->embedForm('result', new SurveyFloatForm());
$this->validatorSchema['result']['value'] = new
sfValidatorNumber(array('required' => false));
break;
case "Text":
$this->embedForm('result', new SurveyTextForm());
$this->validatorSchema['result']['value'] = new
sfValidatorString(array('required' => false));
break;
case "Boolean":
$this->embedForm('result', new SurveyBooleanForm());
$this->validatorSchema['result']['value'] = new
sfValidatorChoice(array('choices' => array(0 => 'N/A', 1 => 'No', 2 =>
'Yes'), 'required' => false));
break;
case "Files":
$this->embedForm('result', new SurveyFilesForm());
break;
}
}
public function saveEmbeddedForms($con = null, $forms = null)
{
if (null === $forms)
{
$result = $this->getValue('result');
$forms = $this->embeddedForms;
foreach ($this->embeddedForms['result'] as $name => $form)
{
if (!isset($result[$name]))
{
unset($forms['result'][$name]);
}
}
}
//die();
return parent::saveEmbeddedForms($con, $forms);
}
}</pre></code>
survey actions.class.php
<code class="php"><pre>
class surveySectionActions extends myFrontModuleActions
{
public function executeShowWidget(dmWebRequest $request)
{
$form = new SurveySectionForm($this->getPageRecord());
if ($request->isMethod('post') && $request->hasParameter($form-
>getName()))
{
$results = $request->getParameter($form->getName());
foreach($results["Questions"] as $question => $answer){
var_dump(($results["Questions"][$question]));die();
}
if ($form->bindAndValid($request))
{
$this->getUser()-
>setFlash('exta_day_added_successfully',true);
$form->save();
$this->redirectBack();
}
}
$this->forms['SurveySection'] = $form;
}
}</pre></code>
Above var_dump produces:
array(5) { ["result"]=> array(2) { ["value"]=> string(1) "1" ["id"]=>
string(0) "" } ["id"]=> string(0) "" ["type"]=> string(7)
"Integer" ["dmuser"]=> string(1) "1" ["question"]=> string(2) "42" }
I'm fairly sure the above it correct. The dmuser and question are both
the ID's because it says the answer is invalid otherwise. However
without the die in the above code I get:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails
(`duediligence`.`survey_answer`, CONSTRAINT
`survey_answer_dmuser_dm_user_id` FOREIGN KEY (`dmuser`) REFERENCES
`dm_user` (`id`))
It is trying to save:
at Doctrine_Connection->exec('INSERT INTO survey_answer (type,
created_at, updated_at) VALUES (?, ?, ?)', array('String', '2012-04-15
14:36:19', '2012-04-15 14:36:19'))
in SF_ROOT_DIR/lib/vendor/diem/symfony/lib/plugins/sfDoctrinePlugin/
lib/vendor/doctrine/lib/Doctrine/Connection.php line 687 ...
at Doctrine_Connection->insert(object('SurveyAnswerTable'),
array('type' => 'String', 'created_at' => '2012-04-15 14:36:19',
'updated_at' => '2012-04-15 14:36:19'))
in SF_ROOT_DIR/lib/vendor/diem/symfony/lib/plugins/sfDoctrinePlugin/
lib/vendor/doctrine/lib/Doctrine/Connection/UnitOfWork.php line
647 ...
Why is it forgetting the values that are set in the form? Without it
having the user and question the object it's not going to save, and
would be useless if it did!
Any help or advise is appreciated.
Thank you
Kye