0

I'm having this issue and I can't find what is wrong. I'm trying to update object before execute the form save method and I do as follow (I wrote the whole class just in case):

class SdrivingMaquinaForm extends BaseSdrivingMaquinaForm {

    protected $current_user;

    public function configure() {
        $this->current_user = sfContext::getInstance()->getUser()->getGuardUser();

        unset($this['updated_at'], $this['created_at']);

        $this->widgetSchema['idempresa'] = new sfWidgetFormInputHidden();
        $id_empresa = $this->current_user->getSfGuardUserProfile()->getIdempresa();
        $this->setDefault('idempresa', $id_empresa);

        $this->widgetSchema['no_emisor'] = new sfWidgetFormDoctrineChoice(array('model' => 'SdrivingEmisor', 'add_empty' => 'Seleccione un Emisor', 'table_method' => 'fillChoice'));
        $this->validatorSchema['idempresa'] = new sfValidatorPass();
        $this->validatorSchema['no_emisor'] = new sfValidatorPass();
    }

    protected function doUpdateObject($values) {
        parent::doUpdateObject($values);

        if (isset($this['no_emisor'])) {
            if ($this->isNew()) {
                $sdrivingMaquinaEmisor = new SdrivingMaquinaEmisor();
                $this->getObject()->setSdrivingMaquinaEmisor($sdrivingMaquinaEmisor);
            } else {
                $sdrivingMaquinaEmisor = $this->getObject()->getSdrivingMaquinaEmisor();
            }

            $sdrivingMaquinaEmisor->setIdemisor($this->values['no_emisor']);
        }
    }
}

This is the schema.yml related to that form:

SdrivingMaquina:
  actAs: 
    Timestampable: ~
  columns:
    idmaquina: { type: integer(8), autoincrement: true, notnull: true, primary: true }
    idempresa: { type: integer(4), notnull: true }
    patente: { type: string(12), notnull: true }
  relations:
    Empresa: { local: idempresa, class: SdrivingEmpresa, type: one, foreignType: one, foreignAlias: MaquinaEmpresa, onDelete: CASCADE, onUpdate: CASCADE }
SdrivingMaquinaEmisor:
  actAs: 
    Timestampable: ~
  columns:
    idmaquinaemisor: { type: integer(8), primary: true, autoincrement: true }
    idmaquina: { type: integer(8), notnull: true }
    idemisor: { type: integer(8), notnull: true }
  relations:
    SdrivingEmisor: { onDelete: CASCADE, local: idemisor, foreign: idemisor, type: one }
    SdrivingMaquina: { onDelete: CASCADE, local: idmaquina, foreign: idmaquina, type: one }

As you may notice none relation is many to many. When I send the form I get this error:

Couldn't call Doctrine_Core::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references.

And I couldn't find where the error is so any help will be appreciated. Also I notice this in the stack trace:

at SdrivingMaquinaForm->doUpdateObject(array('idmaquina' => null, 'idempresa' => '1', 'patente' => 'TB58922', 'no_emisor' => '2'))

Why idmaquina is null? There should go the value of the maquina I'm creating in the same moment. Should I change my logic and update the relation values after save the maquina? In that case how I get the id of the newest maquina created?

EDIT template: _form.php

<?php use_stylesheets_for_form($form) ?>
<?php use_javascripts_for_form($form) ?>

<div class="row-fluid">
    <form action="<?php echo url_for('maquina/' . ($form->getObject()->isNew() ? 'create' : 'update') . (!$form->getObject()->isNew() ? '?idmaquina=' . $form->getObject()->getIdmaquina() . '&idempresa=' . $form->getObject()->getIdempresa() : '')) ?>" method="post" <?php $form->isMultipart() and print 'enctype="multipart/form-data" ' ?>>
        <?php if (!$form->getObject()->isNew()): ?>
            <input type="hidden" name="sf_method" value="put" />
        <?php endif; ?>
        <?php echo $form->renderHiddenFields(true) ?>
        <?php echo $form->renderGlobalErrors() ?>

        <div class="span4">
            <label><?php echo $form['patente']->renderLabel() ?></label>
            <?php echo $form['patente'] ?>
            <span class="help-block"><?php echo $form['patente']->renderError() ?></span>
        </div>
        <div class="span4">
            <label><?php echo $form['no_emisor']->renderLabel('Emisor') ?></label>
            <?php echo $form['no_emisor'] ?>
            <span class="help-block"><?php echo $form['no_emisor']->renderError() ?></span>
        </div>
        <div class="clearfix"></div>
        <p class="right-align-text marginTop">
            <button type="button" class="btn" id="cancel-btn"><?php echo __('Cancelar') ?></button>
            <input type="submit" value="<?php echo __('Guardar') ?>" class="btn btn-success" />
        </p>
    </form>

    <?php if ($sf_user->hasFlash('error')): ?>
        <div class="alert alert-error">
            <h4>Error!</h4>
            <?php echo $sf_user->getFlash('error') ?>
        </div>
    <?php endif; ?>
</div>

<script>
    $(function() {
        $('#cancel-btn').click(function() {
            history.go(-1);
            $('#myTab a[href="#<?php echo $sf_user->getFlash('activeTab', 'usuarios'); ?>"]').tab('show');
        });
    });
</script>

Action class: action.class.php

class maquinaActions extends sfActions {

    public function executeIndex(sfWebRequest $request) {
        $this->sdriving_maquinas = Doctrine_Core::getTable('SdrivingMaquina')->createQuery('a')->execute();
    }

    public function executeNew(sfWebRequest $request) {
        $this->getUser()->setFlash('activeTab', 'maquinas');
        $this->form = new SdrivingMaquinaForm();
    }

    public function executeCreate(sfWebRequest $request) {
        $this->forward404Unless($request->isMethod(sfRequest::POST));
        $this->form = new SdrivingMaquinaForm();
        $this->processForm($request, $this->form);
        $this->setTemplate('new');
    }

    public function executeEdit(sfWebRequest $request) {
        $this->forward404Unless($sdriving_maquina = Doctrine_Core::getTable('SdrivingMaquina')->find(array($request->getParameter('idmaquina'), $request->getParameter('idempresa'))), sprintf('Object sdriving_maquina does not exist (%s).', $request->getParameter('idmaquina'), $request->getParameter('idempresa')));
        $this->form = new SdrivingMaquinaForm($sdriving_maquina);
    }

    public function executeUpdate(sfWebRequest $request) {
        $this->forward404Unless($request->isMethod(sfRequest::POST) || $request->isMethod(sfRequest::PUT));
        $this->forward404Unless($sdriving_maquina = Doctrine_Core::getTable('SdrivingMaquina')->find(array($request->getParameter('idmaquina'), $request->getParameter('idempresa'))), sprintf('Object sdriving_maquina does not exist (%s).', $request->getParameter('idmaquina'), $request->getParameter('idempresa')));
        $this->form = new SdrivingMaquinaForm($sdriving_maquina);
        $this->processForm($request, $this->form);
        $this->setTemplate('edit');
    }

    public function executeDelete(sfWebRequest $request) {
        $this->forward404Unless($sdriving_maquina = Doctrine_Core::getTable('SdrivingMaquina')->find(array($request->getParameter('idmaquina'), $request->getParameter('idempresa'))), sprintf('Object sdriving_maquina does not exist (%s).', $request->getParameter('idmaquina'), $request->getParameter('idempresa')));
        $sdriving_maquina->delete();
        $this->getUser()->setFlash('activeTab', 'maquinas');
        $this->redirect('admin/index');
    }

    protected function processForm(sfWebRequest $request, sfForm $form) {
        $form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
        if ($form->isValid()) {
//            try {
            $sdriving_maquina = $form->save();

            $this->getUser()->setFlash('activeTab', 'maquinas');
            $this->redirect('admin/index');
//            } catch (Exception $e) {
//                $this->getUser()->setFlash('error', 'Los valores no pueden estar duplicados, verifíquelo e inténtelo nuevamente');
//            }
        }
    }

}

EDIT 2

After test what been told to me here are the results:

originalForm: array(5) { ["idmaquina"]=> string(0) "" ["idempresa"]=> string(1) "1" ["_csrf_token"]=> string(32) "54e5e3984c245e60b17abbf32518d95e" ["patente"]=> string(7) "TB58966" ["no_emisor"]=> string(1) "2" }

Fatal error: Call to a member function getValue() on a non-object in /var/www/html/monitor/apps/frontend/modules/maquina/actions/actions.class.php on line 56

So idmaquina never gets a value

EDIT 3: solution The first thing I do was fix the schema.yml (see this post for best information and not repeat the solution here). Then in SdrivingMaquinaForm.class.php file I change this:

protected function doUpdateObject($values) {
    parent::doUpdateObject($values);

    if (isset($this['no_emisor'])) {
        if ($this->isNew()) {
            $sdrivingMaquinaEmisor = new SdrivingMaquinaEmisor();
            $this->getObject()->setSdrivingMaquinaEmisor($sdrivingMaquinaEmisor);
        } else {
            $sdrivingMaquinaEmisor = $this->getObject()->getSdrivingMaquinaEmisor();
        }

        $sdrivingMaquinaEmisor->setIdemisor($this->values['no_emisor']);
        $this->getObject()->getSdrivingMaquinaEmisor()->setIdemisor($this->values['no_emisor']);
    }
}

protected function updateDefaultsFromObject() {
    parent::updateDefaultsFromObject();
    if (isset($this['no_emisor'])) {
        $this->setDefault('no_emisor', $this->getObject()->getSdrivingMaquinaEmisor()->getIdemisor());
    }
} 

of course also I set idempresa at configure() method as follows:

$this->widgetSchema['idempresa'] = new sfWidgetFormInputHidden();
$id_empresa = $this->current_user->getSfGuardUserProfile()->getIdempresa();
$this->setDefault('idempresa', $id_empresa);

That was all, after fix the schema and add the code things works as I want

Community
  • 1
  • 1
Reynier
  • 2,420
  • 11
  • 51
  • 91

1 Answers1

1

I may be wrong but I think you should add the widget and validator for idmaquina field in your form configure() function.

$this->widgetSchema['idmaquina'] = new sfWidgetFormInputHidden();
$this->validatorSchema['idmaquina'] = new sfValidatorChoice(array('choices' => array($this->getObject()->get('idmaquina')), 'empty_value' => $this->getObject()->get('idmaquina'), 'required' => false));

Since you havent created it in your overloaded form, its never saving its value into the form, and when you send the form, idmaquina will be null. You can easily debug it with a simple var_dump of the form field idmaquina.

After changing your form, go to command line and in your symfony project folder, clear symfony cache with: symfony cc

Please add the following code and check for its value:

In doUpdateObject:

doUpdateObject($values){
    echo "values: "; var_dump($values); echo "<br />";
    ///...
}

In processForm:

protected function processForm(sfWebRequest $request, sfForm $form) {
    $originalForm = $request->getParameter($form->getName()), 
    $request->getFiles($form->getName());
    echo "originalForm: "; var_dump($originalForm); echo "<br />";
    echo "idmaquina: " . $originalForm['idmaquina']->getValue(); echo "<br />";
    //...
}

You need to make sure that you are setting and sending the value of idmaquina in your form.

xtrm
  • 966
  • 9
  • 22
  • nop, this isn't the problem I tried and get the same error this drive me crazy – Reynier Jun 25 '13 at 14:01
  • Please add your module template with the form and your actions.class.php with the function which receives the request and form. – xtrm Jun 25 '13 at 14:49
  • Thanks, I will still recommend to add idmaquina to the form, or you wont be able send its value since it will be never be binded inside the form object that you are sending when you press the submit button. Please check my post again and add: the idmaquina widget and validator and also add the debug to your code so we can clarify a bit more whats happening and the values that are really sent with the form. – xtrm Jun 25 '13 at 19:48
  • Please add the idmaquina widget, and the new validator for idmaquina. I have updated the validator. Important to clear symfony cache again! When you reload the form in firefox with F5, use firebug plugin to see if the form field idmaquina has a hidden value already set. Check with firefox if the field idmaquina has value in the form: `` – xtrm Jun 25 '13 at 21:41
  • welcome :) When you can post how you finally solved it it would be perfect so others could also benefit from it – xtrm Jun 26 '13 at 06:17
  • done, I add as **edit 3** the solution to my problem so others can take a look and at least have a idea for where to look if they run in the same mistake – Reynier Jun 26 '13 at 07:14