SilverStripe - DataObject onBeforeWrite上的未定义索引

时间:2018-04-18 11:09:16

标签: php silverstripe silverstripe-4

关于DataObject DataObject扩展,我正在发生此异常:

  

PHP注意:未定义的索引:PrezzoIva

项目全景:在主write()执行之前,必须计算一个值并与其他[...] /** * Classe Prodotto */ class Prodotto extends DataObject { // Dichiarazione Proprietà private static $db = [ [...] 'PrezzoIva' => 'Currency', [...] 属性成对保存。 这是情况(在SS 4.0.3上):

onBeforeWrite

/** * 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(); } 方法:

    /**
     * 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;
        }
    }

上述方法调用的方法:

if (!$this->record['PrezzoIva'])

if (!isset($this->record['PrezzoIva']))更改为onBeforeWrite仍然会抛出异常。

提前感谢您的支持。

更新

似乎通过嵌套onBeforeWrite内的控件显然可以解决问题,但这与业务逻辑不符。在$this->record['PrezzoIva']的第一次尝试时,系统看不到任何elseif然后失败。另一方面,如果控件嵌套write(),如果缺少其他记录,则忽略这些控件。现在我还在努力。 同时,我注意到$this->PrezzoIva调用时没有初始化涉及的字段。这只发生在insert into t (items) values ('A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition:'), ('A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition:' ) , ('A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition:'), ('A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition:' ) , ('A. CARRIER: 1. UNDERCARRIAGE: 1.2 Final Drive System Condition:') , ('A. CARRIER: 1. UNDERCARRIAGE: 1.3 Transmission Condition:'), ('A. CARRIER: 1. UNDERCARRIAGE: 1.3 Transmission Condition:' ), ('B. ENGINE SYSTEM Condition:') , ('B. ENGINE SYSTEM Condition:' ) ; select items , if(items <> @p,@rn:=1,@rn:=@rn+1) rn, @p:=items previousitem from t cross join (select @rn:=0,@p:='') r order by id; +-----------------------------------------------------------------+------+-----------------------------------------------------------------+ | items | rn | previousitem | +-----------------------------------------------------------------+------+-----------------------------------------------------------------+ | A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition: | 1 | A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition: | | A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition: | 2 | A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition: | | A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition: | 3 | A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition: | | A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition: | 4 | A. CARRIER: 1. UNDERCARRIAGE: 1.1 Track System Condition: | | A. CARRIER: 1. UNDERCARRIAGE: 1.2 Final Drive System Condition: | 1 | A. CARRIER: 1. UNDERCARRIAGE: 1.2 Final Drive System Condition: | | A. CARRIER: 1. UNDERCARRIAGE: 1.3 Transmission Condition: | 1 | A. CARRIER: 1. UNDERCARRIAGE: 1.3 Transmission Condition: | | A. CARRIER: 1. UNDERCARRIAGE: 1.3 Transmission Condition: | 2 | A. CARRIER: 1. UNDERCARRIAGE: 1.3 Transmission Condition: | | B. ENGINE SYSTEM Condition: | 1 | B. ENGINE SYSTEM Condition: | | B. ENGINE SYSTEM Condition: | 2 | B. ENGINE SYSTEM Condition: | +-----------------------------------------------------------------+------+-----------------------------------------------------------------+ 9 rows in set (0.00 sec) 。其他字段被正确保存。这是一个例子:

official SS guide

1 个答案:

答案 0 :(得分:0)

针对此特定案例的正确条件解决了这个问题。 在第一个write()之后,如果没有设置this->record['PrezzoIva']或者此值等于零(根据Currency数据类型默认值),则调用该方法:

        // Controllo Record
        if (!$this->isInDb()) {
            $this->setPrezzoIva();
        }
        if ((!isset($this->record['PrezzoIva'])) || ($this->record['PrezzoIva'] == 0)) {
            $this->setPrezzoIva();
        }

关于无数据写入问题,我在这里开了一个新问题:SilverStripe - No data written onBeforeWrite