问题
Following the official SS guide on DataObject
extension, I'm occurring on this exception:
PHP Notice: Undefined index: PrezzoIva
Project panorama: a value must be computed and saved in pair with the other DataObject
properties, before the main write()
execution.
Here's the situation (on SS 4.0.3):
[...]
/**
* 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 (!$this->record['PrezzoIva']) { // <--- This is the line involved
$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 (empty($this->PrezzoIva)) {
$prezzoIva = ($this->PrezzoUnitario * $this->Iva) + $this->PrezzoUnitario;
// Salvataggio IVA
$this->PrezzoIva = $prezzoIva;
}
}
Either changing if (!$this->record['PrezzoIva'])
to if (!isset($this->record['PrezzoIva']))
the exception is still thrown.
Thanks in advance for the support.
UPDATE
Seems that by nesting the controls inside onBeforeWrite
apparently solves the issue, but it's not in accord with the business logic. On the first attempt of onBeforeWrite
, the system doesn't see any $this->record['PrezzoIva']
then fails. On the other side, if the controls being nested with elseif
, in case other records missing, these are ignored. For now I'm still working on it.
Meanwhile, I noticed that the involved field doesn't been initialized neither on write()
calling. And this happens only with $this->PrezzoIva
. The other fields being correcly saved. Here an example:
回答1:
Working on the right condition for this specific case solved the issue.
After the first write()
, if there's no this->record['PrezzoIva']
set or this one is equal to zero (according to Currency
data type default value), the method is invoked:
// Controllo Record
if (!$this->isInDb()) {
$this->setPrezzoIva();
}
if ((!isset($this->record['PrezzoIva'])) || ($this->record['PrezzoIva'] == 0)) {
$this->setPrezzoIva();
}
About the no-data written issue, I opened a new one here: SilverStripe - No data written onBeforeWrite
来源:https://stackoverflow.com/questions/49898205/silverstripe-undefined-index-on-dataobject-onbeforewrite