Search code examples
phpsilverstripesilverstripe-4

SIlverStripe - No data written onBeforeWrite


Related to this issue, a DataObject extended with onBeforeWrite method doesn't write a specific property value on DB. In detail:

DataObject:

[...] 
/**
 * Classe Prodotto
 */
class Prodotto extends DataObject
{
// Dichiarazione Proprietà
private static $db = [
    [...] 
    'PrezzoIva' => 'Currency',
    [...] 

onBeforeWrite method:

/**
     * Metodo gestione azioni salvataggio
     * Calcolo automatico prezzo lordo e scontato
     * Setter
     * @return void
     */
    public function onBeforeWrite()
    {
        // Controllo Record
        if (!$this->isInDb()) {
            $this->setPrezzoIva();
        }
        if ((!isset($this->record['PrezzoIva'])) || ($this->record['PrezzoIva'] == 0)) {
            $this->setPrezzoIva();
        }

        parent::onBeforeWrite();
    }

The method called by the one above:

/**
     * Metodo calcolo prezzo lordo IVA
     * Setter
     * @return void
     */
    public function setPrezzoIva()
    {
        // Controllo IVA
        if ((isset($this->PrezzoIva)) && ($this->PrezzoIva == 0)) {
            $prezzoIva = ($this->PrezzoUnitario * $this->Iva) + $this->PrezzoUnitario;

            // Salvataggio IVA
            $this->PrezzoIva = $prezzoIva;
        }
    }

There's no exception thrown. Basically, both on the first write() as well as in other saves, PrezzoIva is not being updated (it keeps the default one). Here an extract to my DB after few DataObject edits:

DB screen

For now, I not figured out what causing this. A help of any kind will be appreciated.

Thanks in advance everyone.


Solution

  • You have to watch the setters in SilverStripe. SilverStripe uses the __set function.

    When you call $this->PrezzoIva it will search for a method called setPrezzoIva. If it cannot find a method with that name, it will call the method setField. Which will actually set the field like you want.

    So the problem you're experiencing is because your method is called setPrezzoIva. Instead of setting the value, it is excecuting your method.

    To fix this, change

    $this->PrezzoIva = $prezzoIva;
    

    to

    $this->setField('PrezzoIva', $prezzoIva);
    

    On a sidenote, I think Robbie is right, your conditions are too strict.