Zum Inhalt springen Zur Seitenleiste springen

Dieses Thema ist gelöst. Hier finden Sie eine Beschreibung des Problems und der Lösung.

Problem:
Beim Erstellen einer Produktübersetzung über die REST-API wird ein neuer Artikel mit derselben SKU erstellt, anstatt einen Fehler auszugeben, dass bereits eine Übersetzung existiert. Dies führt zu zwei unabhängigen Artikeln mit derselben SKU.

Solution:
Wenn Sie auf dieses Problem stoßen, empfehlen wir Ihnen, den folgenden Code in Ihre

functions.php

Datei einzufügen, nachdem Sie ein vollständiges Backup Ihrer Website erstellt haben. Dieser Code entfernt verwaiste SKUs, die durch die REST-API-Aufrufe entstanden sind.

add_action( 'wcml_before_sync_product', 'fix_orphaned_skus', 2, 10 );
function fix_orphaned_skus( $original_product_id, $post_id ) {
    global $wpdb;
    $sku          = get_post_meta( $original_product_id, '_sku', true );
    $type         = get_post_type( $original_product_id );
    $trid         = apply_filters( 'wpml_element_trid', null, $original_product_id, 'post_' . $type );
    $translations = apply_filters( 'wpml_get_element_translations', null, $trid, 'post_' . $type );
    $others       = $wpdb->get_col( $wpdb->prepare( "SELECT `post_id` FROM $wpdb->postmeta WHERE `meta_key` = '_sku' AND `meta_value` LIKE %s", $sku ) );
    foreach ( $others as $key => $value ) {
        foreach ( $translations as $tr ) {
            if ( $value == $tr->element_id ) {
                unset ( $others[ $key ] );
                continue;
            }
        }

    }
    foreach ( $others as $index => $delete ) {
        wp_delete_post( $delete );
    }
}

Bitte versuchen Sie nach dem Hinzufügen des Codes den Prozess erneut. Sollte diese Lösung nicht relevant erscheinen, öffnen Sie bitte ein neues Support-Ticket im WPML-Supportforum.

Dies ist das technische Support-Forum für WPML – das mehrsprachige WordPress-Plugin.

Mitlesen können alle, doch nur WPML-Kunden können hier Fragen veröffentlichen. Das WPML-Team antwortet im Forum an 6 Tagen pro Woche, 22 Stunden am Tag.

Schlagwörter: ,

Dieses Thema enthält 7 Antworten, hat 2 Stimmen.

Zuletzt aktualisiert von Marcel Vor 1 Jahr, 8 Monaten.

Assistiert von: Marcel.

Autor Beiträge
Dezember 11, 2023 um 1:39 pm #15037769

benjminG

Ich versuche:
Zuerst wird ein Artikel mit SKU 123456789 in Sprache Deutsch (hier Hauptsprache) erstellt:

{
	"name": "Fremdsprachen-Testartikel",
	"sku": "123456789"
}

Nun wird ein Fremdsprachenartikel dieses Artikels erstellt:

{
	"name": "Foreign language test product",
	"lang": "en",
	"translation_of": 10082
}

Dies funktioniert wie erwartet.
Nun wird die 2. Anfrage erneut ausgeführt.

URL der/meiner Website, auf der das Problem auftritt:
nur lokal zugänglich

Erwartet hatte ich zu sehen:
Einen Fehler, dass bereits ein Fremdsprachen-Artikel in dieser Sprache für diesen Artikel besteht.

Stattdessen bekam ich:
Es wird stattdessen ein neuer Artikel erstellt, der den bisherigen ersetzt. Der vorherige Artikel bleibt jedoch vorhanden und ist über die API abrufbar. Er hat die gleiche SKU wie die anderen Artikel, scheint nun aber unabhängig von den anderen Artikeln zu sein. Es bestehen also nun zwei nun unabhängige Artikel, die die gleiche SKU haben, was nicht sein darf.

Dezember 12, 2023 um 8:17 am #15042905

Marcel
Unterstützer

Sprachen: Englisch (English ) Spanisch (Español ) Deutsch (Deutsch )

Zeitzone: Europe/Madrid (GMT+02:00)

Hallo,

bevor Ihr Ticket einem meiner Kollegen zugewiesen wird, erlauben Sie mir bitte, Sie durch einige erste Schritte zur Fehlersuche zu führen.

Können Sie bitte eine Kopie der Seite als zugänglich Staging-Umgebung bereitstellen? Alternativ wäre eine Duplicator Kopie ebenso möglich.

Bitte nehmen Sie dazu ein Video mit Ihren exakten Schritten auf, damit wir das Problem dort reproduzieren können

Vielen Dank!

Freundliche Grüße
Marcel

Dezember 12, 2023 um 8:58 am #15043323

benjminG

Auf welchem Weg soll ich Ihnen die Duplicator-Kopie (131 MB) zur Verfügung stellen?

Dezember 12, 2023 um 9:07 am #15043379

Marcel
Unterstützer

Sprachen: Englisch (English ) Spanisch (Español ) Deutsch (Deutsch )

Zeitzone: Europe/Madrid (GMT+02:00)

Hallo,

Sie können das sichere Eingabeformular verwenden und dort einen Link zu einem Share via Google Drive, WeTransfer etc. hinzufügen.

Vielen Dank!

Freundliche Grüße
Marcel

Dezember 15, 2023 um 6:19 pm #15075759

Marcel
Unterstützer

Sprachen: Englisch (English ) Spanisch (Español ) Deutsch (Deutsch )

Zeitzone: Europe/Madrid (GMT+02:00)

Hallo,

ich kann es so nicht klar reproduzieren. Ich benötige bitte konkrete Schritte, wie ich das Problem reproduzieren kann. Am einfachsten via cURL und dem aktuellen REST-API Key, welchen Sie für den eShop Connector User angelegt haben. Können Sie bitte die exakte Eingabe als cURL URL mit den Parametern bereitstellen?

Freundliche Grüße
Marcel

Dezember 18, 2023 um 9:43 am #15081619

benjminG

Hier der volle Ablauf mit cURL:

- Erstellung Artikel mit SKU 123456789 in Sprache Deutsch (Hauptsprache):
Wichtig: Es darf kein Cookie mitgeschickt werden, dass die Sprache auf eine andere als Deutsch stellt, ansonsten passiert nicht dies, was hier dokumentiert ist.

curl --request POST \
  --url <em><u>versteckter Link</u></em> \
  --header 'Authorization: OAuth oauth_consumer_key="ck_1faa3137b71c3aec93ad5b942033518477087c92", oauth_nonce="qSuFa7dLwg8KsQpWbHgMtMSzScIXFVOa", oauth_signature="WxnEvO7uEnX0lgWivmwFFkaLmGk%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1702890868", oauth_version="1.0"' \
  --header 'Content-Type: application/json' \
  --header 'User-Agent: Insomnia/2023.5.6' \
  --data '{
    "name": "Fremdsprachen-Testartikel",
    "sku": "123456789"
}'

- Erstellung eines Fremdsprachenartikel dieses Artikels in Englisch:

curl --request POST \
  --url <em><u>versteckter Link</u></em> \
  --header 'Authorization: OAuth oauth_consumer_key="ck_1faa3137b71c3aec93ad5b942033518477087c92", oauth_nonce="CMNVZw9oKgXETxBOWNDZgEd4WLu9Jdna", oauth_signature="o%2BUkp%2Bv4YwcKKU4yrE6coUUsvtM%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1702891022", oauth_version="1.0"' \
  --header 'Content-Type: application/json' \
  --header 'User-Agent: Insomnia/2023.5.6' \
  --cookie wp-wpml_current_admin_language_d41d8cd98f00b204e9800998ecf8427e=de \
  --data '{
    "name": "Foreign language test product",
    "lang": "en",
    "translation_of": 10099
}'

- Erneute Ausführung der 2. Request

Ergebnis:

Der neue Artikel 10101 ist nun korrekterweise mit der richtigen Sprache als Übersetzung des Hauptartikels hinterlegt:
Request:

curl --request GET \
  --url <em><u>versteckter Link</u></em> \
  --header 'Authorization: OAuth oauth_consumer_key="ck_1faa3137b71c3aec93ad5b942033518477087c92", oauth_nonce="lTGXfblwLMIlQR6qrYZGQo7CciyNp5Fo", oauth_signature="5zElsCTJLWjgxGs%2FgpWy1Tida1c%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1702891801", oauth_version="1.0"' \
  --header 'User-Agent: Insomnia/2023.5.6' \
  --cookie wp-wpml_current_admin_language_d41d8cd98f00b204e9800998ecf8427e=en

Response:

{
  "id": 10101,
  "name": "Foreign language test product",
  "slug": "foreign-language-test-product-2",
  "permalink": "http:\/\/wpml.ubuntusfl.local\/product\/foreign-language-test-product-2\/?lang=en",
  "date_created": "2023-12-18T10:26:39",
  "date_created_gmt": "2023-12-18T09:26:39",
  "date_modified": "2023-12-18T10:26:56",
  "date_modified_gmt": "2023-12-18T09:26:56",
  "type": "simple",
  "status": "publish",
  "featured": false,
  "catalog_visibility": "visible",
  "description": "",
  "short_description": "",
  "sku": "123456789",
  "price": "",
  "regular_price": "",
  "sale_price": "",
  "date_on_sale_from": null,
  "date_on_sale_from_gmt": null,
  "date_on_sale_to": null,
  "date_on_sale_to_gmt": null,
  "on_sale": false,
  "purchasable": false,
  "total_sales": 0,
  "virtual": false,
  "downloadable": false,
  "downloads": [],
  "download_limit": -1,
  "download_expiry": -1,
  "external_url": "",
  "button_text": "",
  "tax_status": "taxable",
  "tax_class": "",
  "manage_stock": false,
  "stock_quantity": null,
  "backorders": "no",
  "backorders_allowed": false,
  "backordered": false,
  "low_stock_amount": null,
  "sold_individually": false,
  "weight": "",
  "dimensions": {
    "length": "",
    "width": "",
    "height": ""
  },
  "shipping_required": true,
  "shipping_taxable": true,
  "shipping_class": "",
  "shipping_class_id": 0,
  "reviews_allowed": true,
  "average_rating": "0.00",
  "rating_count": 0,
  "upsell_ids": [],
  "cross_sell_ids": [],
  "parent_id": 0,
  "purchase_note": "",
  "categories": [
    {
      "id": 44,
      "name": "Uncategorized",
      "slug": "uncategorized"
    }
  ],
  "tags": [],
  "images": [],
  "attributes": [],
  "default_attributes": [],
  "variations": [],
  "grouped_products": [],
  "menu_order": 0,
  "price_html": "",
  "related_ids": [
    7589,
    7657,
    7656
  ],
  "meta_data": [
    {
      "id": 47818,
      "key": "wcml_sync_hash",
      "value": {
        "postmeta_fields": "6c0c611c2635ea2cfea13a13f459ab35"
      }
    },
    {
      "id": 47819,
      "key": "attr_label_translations",
      "value": []
    },
    {
      "id": 47825,
      "key": "_children",
      "value": []
    }
  ],
  "stock_status": "instock",
  "has_options": false,
  "post_password": "",
  "translations": {
    "de": "10099",
    "en": "10101"
  },
  "lang": "en",
  "_links": {
    "self": [
      {
        "href": "http:\/\/wpml.ubuntusfl.local\/wp-json\/wc\/v3\/products\/10101"
      }
    ],
    "collection": [
      {
        "href": "http:\/\/wpml.ubuntusfl.local\/wp-json\/wc\/v3\/products"
      }
    ]
  }
}

Jedoch existiert der bisherige Fremdsprachenartikel weiterhin:
Request:

curl --request GET \
  --url <em><u>versteckter Link</u></em> \
  --header 'Authorization: OAuth oauth_consumer_key="ck_1faa3137b71c3aec93ad5b942033518477087c92", oauth_nonce="bdZMGq0SvBRPhtXtBrFutxRvssb087Uj", oauth_signature="Vb5800LAannx2OsYWMhmREEXM%2Fg%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1702891918", oauth_version="1.0"' \
  --header 'User-Agent: Insomnia/2023.5.6' \
  --cookie wp-wpml_current_admin_language_d41d8cd98f00b204e9800998ecf8427e=en

Response:

{
  "id": 10100,
  "name": "Foreign language test product",
  "slug": "foreign-language-test-product",
  "permalink": "http:\/\/wpml.ubuntusfl.local\/product\/foreign-language-test-product\/",
  "date_created": "2023-12-18T10:26:39",
  "date_created_gmt": "2023-12-18T09:26:39",
  "date_modified": "2023-12-18T10:26:55",
  "date_modified_gmt": "2023-12-18T09:26:55",
  "type": "simple",
  "status": "publish",
  "featured": false,
  "catalog_visibility": "visible",
  "description": "",
  "short_description": "",
  "sku": "123456789",
  "price": "",
  "regular_price": "",
  "sale_price": "",
  "date_on_sale_from": null,
  "date_on_sale_from_gmt": null,
  "date_on_sale_to": null,
  "date_on_sale_to_gmt": null,
  "on_sale": false,
  "purchasable": false,
  "total_sales": 0,
  "virtual": false,
  "downloadable": false,
  "downloads": [],
  "download_limit": -1,
  "download_expiry": -1,
  "external_url": "",
  "button_text": "",
  "tax_status": "taxable",
  "tax_class": "",
  "manage_stock": false,
  "stock_quantity": null,
  "backorders": "no",
  "backorders_allowed": false,
  "backordered": false,
  "low_stock_amount": null,
  "sold_individually": false,
  "weight": "",
  "dimensions": {
    "length": "",
    "width": "",
    "height": ""
  },
  "shipping_required": true,
  "shipping_taxable": true,
  "shipping_class": "",
  "shipping_class_id": 0,
  "reviews_allowed": true,
  "average_rating": "0.00",
  "rating_count": 0,
  "upsell_ids": [],
  "cross_sell_ids": [],
  "parent_id": 0,
  "purchase_note": "",
  "categories": [
    {
      "id": 44,
      "name": "Uncategorized",
      "slug": "uncategorized"
    }
  ],
  "tags": [],
  "images": [],
  "attributes": [],
  "default_attributes": [],
  "variations": [],
  "grouped_products": [],
  "menu_order": 0,
  "price_html": "",
  "related_ids": [
    10101,
    7656,
    7657,
    7589
  ],
  "meta_data": [
    {
      "id": 47791,
      "key": "wcml_sync_hash",
      "value": {
        "postmeta_fields": "6c0c611c2635ea2cfea13a13f459ab35"
      }
    },
    {
      "id": 47792,
      "key": "attr_label_translations",
      "value": []
    },
    {
      "id": 47798,
      "key": "_children",
      "value": []
    }
  ],
  "stock_status": "instock",
  "has_options": false,
  "post_password": "",
  "translations": [],
  "_links": {
    "self": [
      {
        "href": "http:\/\/wpml.ubuntusfl.local\/wp-json\/wc\/v3\/products\/10100"
      }
    ],
    "collection": [
      {
        "href": "http:\/\/wpml.ubuntusfl.local\/wp-json\/wc\/v3\/products"
      }
    ]
  }
}

Angemerkt sei hierbei, dass der Artikel nicht gelöscht, sondern veröffentlicht ist (siehe status).
Ausserdem sei anzumerken, dass dieser Artikel keine lang-Eigenschaft hat und die Eigenschaft translations ein leeres Array ist.
Auf dem WordPress-Admin-Panel ist der Artikel übrigens nicht mehr gelistet.
Die SKU ist wie erwartet immer noch 123456789. Es existieren nun also zwei unabhängige Artikel in der gleichen Sprache mit gleicher SKU, was nicht sein darf.

Ich hoffe, dass der Fehler nun reproduzierbar ist.

Dezember 22, 2023 um 11:39 am #15116599

Marcel
Unterstützer

Sprachen: Englisch (English ) Spanisch (Español ) Deutsch (Deutsch )

Zeitzone: Europe/Madrid (GMT+02:00)

Danke für die detaillierten Infos. Wir prüfen es und melden uns wieder bei Ihnen.

Freundliche Grüße
Marcel

Januar 4, 2024 um 3:50 pm #15152191

Marcel
Unterstützer

Sprachen: Englisch (English ) Spanisch (Español ) Deutsch (Deutsch )

Zeitzone: Europe/Madrid (GMT+02:00)

Hallo,

Das Problem ist, dass das Custom Field _sku so eingestellt ist, dass es von der WPML Core Logik kopiert wird. Derzeit gibt es eine ziemlich rudimentäre Logik, die die SKU-Prüfung handhabt, aber sie scheint nur im Backend und nicht über REST-API-Aufrufe richtig zu funktionieren.

Eine mögliche Lösung könnte dieser Workaround sein. Fügen Sie den Code bitte nach einem vollen Backup in Ihrer functions.php ein und versuchen Sie den Prozess erneut:

add_action( 'wcml_before_sync_product', 'fix_orphaned_skus', 2, 10 );
function fix_orphaned_skus( $original_product_id, $post_id ) {
	global $wpdb;
	$sku          = get_post_meta( $original_product_id, '_sku', true );
	$type         = get_post_type( $original_product_id );
	$trid         = apply_filters( 'wpml_element_trid', null, $original_product_id, 'post_' . $type );
	$translations = apply_filters( 'wpml_get_element_translations', null, $trid, 'post_' . $type );
	$others       = $wpdb->get_col( $wpdb->prepare( "SELECT `post_id` FROM $wpdb->postmeta WHERE `meta_key` = '_sku' AND `meta_value` LIKE %s", $sku ) );
	foreach ( $others as $key => $value ) {
		foreach ( $translations as $tr ) {
			if ( $value == $tr->element_id ) {
				unset ( $others[ $key ] );
				continue;
			}
		}

	}
	foreach ( $others as $index => $delete ) {
		wp_delete_post( $delete );
	}
}

Funktioniert dies für Sie?

Freundliche Grüße
Marcel

Januar 8, 2024 um 9:09 am #15159013

benjminG

Dies scheint zu funktionieren, ist aber keine permanente Lösung. Es wird für uns evtl. nicht möglich sein, bei allen Kunden dieses Snippet einzuzufügen.

Statt der Ersetzung des Artikels wäre es eher wünschenswert, dass die Anfrage abgelehnt werden würde, wie dies sonst z.B. bei doppelter SKU passiert.

Trotzdem danke für die Unterstützung.