Workaround-Skript: Attribute von Parentartikel übertragen

Hallo zusammen,
ich benutze CE 4.2.0_23610 mit mehrdimensionalen Varianten. Dabei hatte ich das Problem, dass ich die Attribute der Elternartikel auf alle ihre Kinder/Varianten übertragen musste - ein Riesenaufwand und dabei sehr fehleranfällig.
Ich habe mir auf die Schnelle daher mit einem uneleganten, aber effektiven PHP-Skript geholfen. Vielleicht kann das ja noch jemand gebrauchen. (Vorsicht: Ich übernehme natürlich keine Gewähr! Das Skript muss in jedem Fall angepasst werden und kann nur als Basis verwendet werden…)

Viel Spaß damit…
floko


<?php
// workaround script to copy attributes from parent to variants

$mysql_user = "YOUR-DB-NAME";
$hostname   = "YOUR-HOST-NAME";	
$mysql_pw   = "YOUR-PASSWORD";

$link = mysql_connect($hostname, $mysql_user, $mysql_pw);
if (!$link) 
{
  		die('Could not connect: ' . mysql_error());
}
	
// set UTF8 for each connection!!!!
mysql_query("SET NAMES 'utf8'", $link);

?>
<h3>Copy attributes from parents to all children/variants</h3>
<?php

// ###### functions

function generateoxid ($someval1, $someval2) 
{ 
  // generates OXID for new entries in Oxid eSales database tables
  // call e.g.: generateoxid($row->oxartnum, $child)     
  $newstr = $someval1. $someval2;    
  return MD5($newstr);
} // function generateoxid

function attr_exists($id, $link)
{
  $exists = FALSE;
  $sql = "
        SELECT OXID 
        FROM YOUR-DB-NAME.oxobject2attribute
        WHERE 
        OXID = '".$id."'        
  ";

  $res = object_query($sql);
  if (mysql_num_rows($res) > 0) $exists = TRUE;
  
  return $exists;
} // function attr_exists

function object_query($sql) {
	// executes sql query
	// returns object

	$result = mysql_query($sql);

	if (!$result) {
		echo 'MySQL Error: ' . mysql_error();
		exit;
	}	

	return $result;

	mysql_free_result($result);
  
} // object_query()

// ######### end: functions

// SELECT ALL PARENT IDs
$sql = "
    SELECT t1.OXID, t1.OXARTNUM
    FROM YOUR-DB-NAME.oxarticles t1    
    WHERE t1.OXPARENTID = ''
";             

$res = object_query($sql);
       
$i = 0;               
while ($row = mysql_fetch_object($res)) 
{      
  $i++;      
  echo $i . " - " . $row->OXID . " - " . $row->OXARTNUM . " <br />";
  
  // SELECT ALL ATTRIBUTES OF THIS ID
  $sql2 = "
    SELECT t1.OXATTRID, t1.OXVALUE,
    t2.OXTITLE 
    FROM YOUR-DB-NAME.oxobject2attribute t1
    RIGHT JOIN YOUR-DB-NAME.oxattribute t2
    ON (t1.OXATTRID = t2.OXID)
    WHERE t1.OXOBJECTID = '".$row->OXID."'
    ";  
    
   //echo "SQL2 = " . $sql2 . " <br />";    
    
  $res2 = object_query($sql2); 
  while ($row2 = mysql_fetch_object($res2)) 
  {
        
    if ($row2->OXVALUE != "") 
    {
     // if there is anything to pass to children from this attribute
          
     echo "<br /> ----- Transfer: " . $row2->OXTITLE . " - OXVALUE=" . $row2->OXVALUE . " <br />";
    
     // NEXT: Loop through all children!!! 
     $sql3 = "
      SELECT t1.OXID, t1.OXARTNUM, t1.OXVARSELECT
      FROM YOUR-DB-NAME.oxarticles t1    
      WHERE t1.OXPARENTID = '".$row->OXID."'   
      AND NOT t1.OXVARSELECT = ''
     ";      
     $res3 = object_query($sql3); 
     
    while ($row3 = mysql_fetch_object($res3)) 
    {   
          
      echo "---------- OXARTNUM: " . $row3->OXARTNUM .  " ".$row3->OXVARSELECT." ATTRIBUTE: " . $row2->OXTITLE . " <br />";
      
      if (trim($row3->OXVARSELECT == "")) echo "!!!!!!!!!!! OXVARSELECT EMPTY!! #################### <br /><br />";
      
      $variantname = $row3->OXARTNUM . " " . $row3->OXVARSELECT;
      
      $newid = generateoxid($row2->OXATTRID, $variantname);
      
      $sql4 = "
        INSERT INTO YOUR-DB-NAME.oxobject2attribute
        SET 
        OXID = '".$newid."',
        OXOBJECTID = '".$row3->OXID."',
        OXATTRID = '".$row2->OXATTRID."',
        OXVALUE = '".$row2->OXVALUE."',
        OXPOS = 0,
        OXVALUE = '".$row2->OXVALUE."'      
      ";      
      
      //echo $sql4;
            
      // execute
      if (!attr_exists($newid, $link)) 
      {
        $res4 = object_query($sql4);
      } 
      else 
      {
        echo "***** Attribute already exists!!!!!!!!!!! <br /><br />";
      }      
       
      } // while row3       
    } // if value != ""
  }  // while row2  
} // while  row

echo "<p>Done.</p>";
?>

super. Danke!

[QUOTE=Marco Steinhaeuser;34695]super. Danke![/QUOTE]
Also “super” würde ich das nicht unbedingt nennen.

Weil das Skript gnadenlos die objektorientierten Konzepte von OXID aushebelt.

Das war keine Bewertung der Code-Qualität :slight_smile:

Gruß

Hallo Avenger,
natürlich hast Du völlig recht - daher ist es ja auch ein “Workaround” und wie beschrieben ziemlich “unelegant”.
Auf eine schönere Lösung, die sich nahtlos in die Oxid-Umgebung integriert, konnte ich nicht warten; zum selbst Programmieren habe ich erst recht keine Zeit.
Ich könnte mir vorstellen, daß es einigen CE-Nutzern ähnlich geht…

VG
floko

Einfach die details.php entsprechend anpassen, dass eben die Attribute der Vaterartikel mit einbezogen werden.

Hatte das selbe Problem, hab leider nirgendwo eine Lösung gefunden, also habe ich mir eine gebaut.

public function getAttributes()
    {
        if ( $this->_aAttributes === null ) {
            // all attributes this article has
            $aArtAttributes = $this->getProduct()->getAttributes();
			// If has parent, get parent attributes
			if ( ( $oParent = $this->_getParentProduct( $this->getProduct()->oxarticles__oxparentid->value ) ) ) {
                $aArtParentAttributes = $oParent->getAttributes();
            }
	            //making a new array for backward compatibility
            $this->_aAttributes = false;

			// instead of $sKey i use $oAttribute->oxattribute__oxtitle->value so that recurring attributes will be overwritten
            if ( count( $aArtParentAttributes ) ) {
                foreach ( $aArtParentAttributes as $sKey => $oAttribute ) {
                    $this->_aAttributes[$oAttribute->oxattribute__oxtitle->value] = new stdClass();
                    $this->_aAttributes[$oAttribute->oxattribute__oxtitle->value]->title = $oAttribute->oxattribute__oxtitle->value;
                    $this->_aAttributes[$oAttribute->oxattribute__oxtitle->value]->value = $oAttribute->oxattribute__oxvalue->value;
                }
            }
			if ( count( $aArtAttributes ) ) {
                foreach ( $aArtAttributes as $sKey => $oAttribute ) {
                    $this->_aAttributes[$oAttribute->oxattribute__oxtitle->value] = new stdClass();
                    $this->_aAttributes[$oAttribute->oxattribute__oxtitle->value]->title = $oAttribute->oxattribute__oxtitle->value;
                    $this->_aAttributes[$oAttribute->oxattribute__oxtitle->value]->value = $oAttribute->oxattribute__oxvalue->value;
                }
            }
        }
        return $this->_aAttributes;
    }