Article_main.php: Methode save() überladen

Hallo zusammen,

ich versuche die Methode save() der Klasse Article_Main in der Datei /application/controllers/admin/article_main.php zu überladen.
Hintergrund ist die Anforderung, einen Artikel bei der Neuanlage mit bestimmten Eigenschaften anzulegen (z.B. dass der Preisalarm deaktiviert ist oder dass der Lieferstatus auf Fremdlager steht).

Wenn ich die Methode save() mit einem eigenen Modul überlade, funktioniert jedoch nicht mehr die Methode getEditObjectId(), welche innerhalb der Methode save() verwendet wird. Die Methode getEditObjectId() wird verwendet, um zu kontrollieren, ob beim Speichern ein neuer Artikel angelegt werden soll oder ob ein existierender Artikel geändert werden soll. Dies hat zur Folge, dass die Methode bei einer Artikelneuanlage nicht mehr den Wert “-1” zurückgibt, so dass ich in einen falschen If-Zweig laufe und die Artikelneuanlage nicht richtig funktioniert.

Hat jemand eine Idee, wo der Fehler liegen könnte?

Viele Grüße und besten Dank!

[QUOTE=Pauleo77;188281]
Hat jemand eine Idee, wo der Fehler liegen könnte?[/QUOTE]

Ja, an Deiner Erweiterung :wink:

''extend' => array(
'article_main' => 'vendor/modulname/overload_article_main',
...
	 ),
class overload_article_main extends overload_article_main_parent
{
	public function save()
    {
        $soxId = $this->getEditObjectId();
		echo $soxId;

		parent::save();
    }
}

Ohne Quelltext ist es immer schwierig, zu helfen. Das obige sollte in jedem Fall funktionieren. Sonst zeig mal, was Du geschrieben hast.

[QUOTE=rubbercut;188282]Ja, an Deiner Erweiterung ;)[/QUOTE]
:slight_smile:

[QUOTE=rubbercut;188282]Ohne Quelltext ist es immer schwierig, zu helfen. Das obige sollte in jedem Fall funktionieren. Sonst zeig mal, was Du geschrieben hast.[/QUOTE]
Dein Beispielcode funktioniert leider auch schon nicht. Bei der Artikelneuanlage ergibt die Ausgabe von

echo $soxId;

nicht “-1”, sondern “-1dc9912cea923f3127f68137efa41cfde”.
Es handelt sich hierbei meines Erachtens um die Ausgabe “-1” + die oxid (article id) des neu anzulegenden Artikels. Das bedeutet, dass die Methode getEditObjectId() bei der Artikelneuanlage einen falschen Rückgabewert liefert.

Mein Code sieht wie folgt aus (die zwei rot markierten Stellen sind meine Änderungen am Originalcode) :

class overload_article_main extends overload_article_main_parent
{      
	
    /**
     * Saves changes of article parameters.
     */
    public function save()
    {
        parent::save();

        $oConfig = $this->getConfig();
        $soxId = $this->getEditObjectId();
        $aParams = $oConfig->getRequestParameter("editval");
	echo $soxId;
        // default values
        $aParams = $this->addDefaultValues($aParams);

        // null values
        if (isset($aParams['oxarticles__oxvat']) && $aParams['oxarticles__oxvat'] === '') {
            $aParams['oxarticles__oxvat'] = null;
        }

        // varianthandling
        $soxparentId = $oConfig->getRequestParameter("oxparentid");
        if (isset($soxparentId) && $soxparentId && $soxparentId != "-1") {
            $aParams['oxarticles__oxparentid'] = $soxparentId;
        } else {
            unset($aParams['oxarticles__oxparentid']);
        }

        $oArticle = oxNew("oxarticle");
        $oArticle->setLanguage($this->_iEditLang);

        if ($soxId != "-1") {
            $oArticle->loadInLang($this->_iEditLang, $soxId);
        } else {
            $aParams['oxarticles__oxid'] = null;			
	    $aParams['oxarticles__oxblfixedprice'] = 1;			
            $aParams['oxarticles__oxissearch'] = 1;
            $aParams['oxarticles__oxstockflag'] = 4;
            if (empty($aParams['oxarticles__oxstock'])) {
                $aParams['oxarticles__oxstock'] = 0;
            }

            // shopid
            $aParams['oxarticles__oxshopid'] = oxRegistry::getSession()->getVariable("actshop");

            if (!isset($aParams['oxarticles__oxactive'])) {
                $aParams['oxarticles__oxactive'] = 0;
            }
        }

        //article number handling, warns for artnum dublicates
        if (isset($aParams['oxarticles__oxartnum']) && strlen($aParams['oxarticles__oxartnum']) > 0 &&
            $oConfig->getConfigParam('blWarnOnSameArtNums') &&
            $oArticle->oxarticles__oxartnum->value != $aParams['oxarticles__oxartnum']
        ) {
            $sSelect = "select oxid from " . getViewName('oxarticles');
            $sSelect .= " where oxartnum = '" . $aParams['oxarticles__oxartnum'] . "'";
            $sSelect .= " and oxid != '" . $aParams['oxarticles__oxid'] . "'";
            if ($oArticle->assignRecord($sSelect)) {
                $this->_aViewData["errorsavingatricle"] = 1;
            }
        }


        // #905A resetting article count in price categories if price has been changed
        $sOxIdField = 'oxarticles__oxid';
        $sPriceField = 'oxarticles__oxprice';
        $sActiveField = 'oxarticles__oxactive';
        $sVendorField = 'oxarticles__oxvendorid';
        $sManufacturerField = 'oxarticles__oxmanufacturerid';
        if (isset($aParams[$sPriceField]) && $aParams[$sPriceField] != $oArticle->$sPriceField->value) {
            $this->resetCounter("priceCatArticle", $oArticle->$sPriceField->value);
        }

        $aResetIds = array();
        if (isset($aParams[$sActiveField]) && $aParams[$sActiveField] != $oArticle->$sActiveField->value) {
            //check categories
            $this->_resetCategoriesCounter($oArticle->$sOxIdField->value);

            // vendors
            $aResetIds['vendor'][$oArticle->$sVendorField->value] = 1;
            $aResetIds['manufacturer'][$oArticle->$sManufacturerField->value] = 1;
        }

        // vendors
        if (isset($aParams[$sVendorField]) && $aParams[$sVendorField] != $oArticle->$sVendorField->value) {
            $aResetIds['vendor'][$aParams[$sVendorField]] = 1;
            $aResetIds['vendor'][$oArticle->$sVendorField->value] = 1;
        }

        // manufacturers
        if (isset($aParams[$sManufacturerField]) &&
            $aParams[$sManufacturerField] != $oArticle->$sManufacturerField->value) {

            $aResetIds['manufacturer'][$aParams[$sManufacturerField]] = 1;
            $aResetIds['manufacturer'][$oArticle->$sManufacturerField->value] = 1;
        }

        // resetting counts
        $this->_resetCounts($aResetIds);

        $oArticle->setLanguage(0);

        //triming spaces from article title (M:876)
        if (isset($aParams['oxarticles__oxtitle'])) {
            $aParams['oxarticles__oxtitle'] = trim($aParams['oxarticles__oxtitle']);
        }

        $oArticle->assign($aParams);
        $oArticle->setArticleLongDesc($this->_processLongDesc($aParams['oxarticles__oxlongdesc']));
        $oArticle->setLanguage($this->_iEditLang);
        $oArticle = oxRegistry::get("oxUtilsFile")->processFiles($oArticle);
        $oArticle->save();

        // set oxid if inserted
        if ($soxId == "-1") {
            $sFastCat = $oConfig->getRequestParameter("art_category");
            if ($sFastCat != "-1") {
                $this->addToCategory($sFastCat, $oArticle->getId());
            }
        }

        // @deprecated v5.3 (2016-05-04); Tags will be moved to own module.
        //saving tags
        if (isset($aParams['tags'])) {
            $sTags = $aParams['tags'];
            if (!trim($sTags)) {
                $sTags = $oArticle->oxarticles__oxsearchkeys->value;
            }
            $aInvalidTags = $this->_setTags($sTags, $oArticle->getId());
            if (!empty($aInvalidTags)) {
                $this->_aViewData["invalid_tags"] = implode(', ', $aInvalidTags);
            }
        }
        // END deprecated
        
        $this->setEditObjectId($oArticle->getId());
    }
	
}

Entferne mal

parent::save(); 

Du fügst ja nichts hinzu sondern lässt quasi alles “2x durchlaufen”. So müsste er theoretisch 2 gleiche Artikel anlegen, d.h. einmal mit der normalen Oxid und einmal mit -1. Kannst ja mal nach der Artikelnummer suchen, ob eventuell 2 Artikel vorliegen.

Klasse! Jetzt funktioniert alles. :slight_smile:

Kannst Du mir bitte noch mal kurz erklären, wozu

parent::save();

gut ist? Das ist mir irgendwie nicht ganz klar. :confused:

Ansonsten würde mich noch interessieren, ob es unproblematisch ist, dass ich die Codezeile jetzt einfach auskommentiert habe oder ob mir das jetzt an anderer Stelle wieder auf die Füße fallen kann.

Viele Grüße!

Du erweiterst mit Deinem Modul article_main. Mit parent::save(); wird die Methode dort aufgerufen. Da Du alles kopiert und ergänzt hast, wird alles 2x ausgeführt.

http://php.net/manual/pl/keyword.parent.php

Solange kein anderes Modul dort ansetzt, kannst es so lassen. Ansonsten müsste man es eigentlich noch in der Form ändern, dass andere, in der Reihenfolge nachkommende, Extensions auch ansetzen können:

public function save()
    { $meincase = wasweissich;
        if($meincase == true){
        mach das, was ich will...
       }
       else{
      parent::save();
      }
    }

Danke für die Erklärung und den Link. Das ist einleuchtend, dass die Codezeile

parent::save();

zur doppelten Ausführung in meinem eigenen Modul führt.

Was ich aber dann wiederum nicht ganz nachvollziehen kann, warum die Codezeile in der Originalmethode (also ohne eine Überladung) nicht ebenfalls zu einer doppelten Ausführung führt.
Dort wird doch auch die Methode save() ausgeführt und innerhalb der Methode parent::save().

parent::save(); führt die save()-Methode der nächsten übergeordneten Klasse in der Vererbungskette aus. Die Vererbungskette von article_main (von unten nach oben) ist:
Article_Main->oxAdminDetails->oxAdminView->oxView->oxSuperCfg

Also parent::save(); in Article_Main führt save() in oxAdminDetails aus, hier gibt es kein save(), also wird die von oxAdminView aufgerufen, und dort steht:

    public function save()
    {
        $this->resetContentCache();
    }

Da wird also nichts gespeichert, sondern nur der Cache geleert.
Wenn du in deinem Modul parent::save(); ausführst, wird die Methode von Article_Main aufgerufen, da wird der Eintrag gespeichert.

Wenn du das parent::save() weglässt, wird nur deine Methode ausgeführt, also nur einmal gespeichert, aber da das parent::save() aus Article_Main auch nicht ausgeführt wird, müsstest du die Zeile $this->resetContentCache(); an dieser Stelle selbst aufrufen. Methoden zu kopieren und den parent-Aufruf wegzulassen geht auch nur einmal, ein weiteres Modul was das gleiche macht funktioniert nicht.

Vielen Dank für die ausführliche Erklärung.
Jetzt habe ich es verstanden. :slight_smile: