'de', 1 => 'en']; private $taxationByDestinationCountry; private $orderSearchLimit; private $category_identifier; private $create_products; private $mirakl_error_text_product_missing; private $offer_field_map; private $product_field_map; public function __construct($app, $intern = false) { $this->app = $app; $this->intern = $intern; if ($intern) return; } /* * See widget.shopexport.php, ShowExtraeinstellungen() */ public function EinstellungenStruktur() { $einstellungen = [ 'ausblenden' => ['abholmodus' => ['ab_nummer', 'zeitbereich']], 'functions' => ['getarticlelist'], 'felder' => [ 'protokoll' => [ 'typ' => 'checkbox', 'bezeichnung' => '{|Protokollierung im Logfile|}:' ], 'apikey' => [ 'typ' => 'text', 'bezeichnung' => '{|API Key|}:', 'size' => 40, ], 'shopurl' => [ 'typ' => 'text', 'bezeichnung' => '{|Shop URL|}:', 'size' => 40, ], 'mirakl_shopid' => [ 'typ' => 'text', 'bezeichnung' => '{|Shop ID des Shops|}:', 'size' => 40, 'info' => 'optional, int64' ], 'category_identifier_source' => [ 'typ' => 'select', 'bezeichnung' => '{|Katalogkategorie-Typ|}:', 'size' => 40, 'info' => 'Woher soll die Katalogkategorie des jeweiligen Artikels bezogen werden?', 'default' => 'feld', 'optionen' => ['feld' => '{|Feld|}', 'freifeld' => '{|Freifeld|}', 'eigenschaft' => '{|Eigenschaft|}', 'wert' => '{|Fester Wert|}'] ], 'category_identifier_source_value' => [ 'typ' => 'text', 'bezeichnung' => '{|Katalogkategorie-Wert|}:', 'size' => 40, 'info' => '', 'default' => 'kategoriename' ], 'create_products' => [ 'typ' => 'checkbox', 'bezeichnung' => '{|Produkte anlegen|}:', 'size' => 40, 'info' => 'Produkte automatisch anlegen wenn sie nicht existieren' ], 'mirakl_error_text_product_missing' => [ 'typ' => 'text', 'bezeichnung' => '{|Fehlertext Produkt fehlt|}:', 'size' => 40, 'info' => 'Der Fehlertext der anzeigt dass das Produkt nicht existiert (Angebotsimport, Fehlerbericht)', 'default' => 'The product does not exist' ], 'product_field_map' => [ 'typ' => 'textarea', 'bezeichnung' => '{|Zuordnung Produkt-Felder je Kategorie (JSON)|}:', 'cols' => 80, 'rows' => 20, 'info' => 'Die Felder werden vom Mirakl-Betreiber vorgegeben. Ist keine Kategorie definiert, gilt der Eintrag für alle Artikel. Jedes Feld kann wie folgt zugeordnet werden:
Artikelfeld: "Mirakel-Feldname": {"feld": "xyz"} oder kurz "Mirakel-Feldname": "xyz",
Freifeld: "Mirakel-Feldname": {"freifeld": "Bezeichnung in Shop"} (Siehe Reiter "Freifelder"),
Eigenschaft: "Mirakel-Feldname": {"eigenschaft": "Eigenschaftenname xyz"},
Fester Wert: "Mirakel-Feldname": {"wert": "xyz"}

Zusatzfelder zusätzlich mit der Eigenschaft "zusatzfeld": true versehen: z.B. "Mirakel-Feldname": {"feld": "name_de", "zusatzfeld": true}', 'placeholder' => '[ { "kategorien": [ "Schuhe", "Hosen" ], "felder": { "category": {"freifeld": "Kategorie"}, "Product.SellerProductID": {"feld": "nummer"}, "SHOP.PRODUCT.TITLE": {"feld": "nummer"}, "ATT.GLOBAL.Brandname": {"feld": "preis"}, "Product.BaseUnit": {"freifeld": "Kategorie"}, "ATT.GLOBAL.NoCUperOU": {"eigenschaft": "Mirakl Steuertext"}, "ATT.GLOBAL.NoCUperOU__UNIT": {"wert": "false","zusatzfeld": true}, "Product.TaxIndicator": {"wert": "1","zusatzfeld": true} } } ]' ], 'offer_field_map' => [ 'typ' => 'textarea', 'bezeichnung' => '{|Zuordnung Angebots-Felder je Kategorie (JSON)|}:', 'cols' => 80, 'rows' => 20, 'info' => 'Die Felder werden vom Mirakl-Betreiber vorgegeben. Ist keine Kategorie definiert, gilt der Eintrag für alle Artikel. Jedes Feld kann wie folgt zugeordnet werden:
Artikelfeld: "Mirakel-Feldname": {"feld": "xyz"} oder kurz "Mirakel-Feldname": "xyz",
Freifeld: "Mirakel-Feldname": {"freifeld": "Bezeichnung in Shop"} (Siehe Reiter "Freifelder"),
Eigenschaft: "Mirakel-Feldname": {"eigenschaft": "Eigenschaftenname xyz"},
Fester Wert: "Mirakel-Feldname": {"wert": "xyz"}

Zusatzfelder zusätzlich mit der Eigenschaft "zusatzfeld": true versehen: z.B. "Mirakel-Feldname": {"feld": "name_de", "zusatzfeld": true}', 'placeholder' => '[ { "kategorien": [ "Schuhe", "Hosen" ], "felder": { "product_id_type": {"wert": "SHOP_SKU"}, "product_id": {"feld": "nummer"}, "shop_sku": {"feld": "nummer"}, "price": {"feld": "preis"}, "description": {"freifeld": "Kategorie"}, "internal_description": {"eigenschaft": "Mirakl Steuertext"}, "reversecharge": {"wert": "false","zusatzfeld": true}, "warehouse": {"wert": "1","zusatzfeld": true}, "quantity": {"feld": "anzahl_lager"} } } ]' ], 'Artikelfelder' => [ 'heading' => 'Zusatzinformationen', 'typ' => 'info', 'text' => 'Folgende Artikelfelder stehen zur Verfügung:', 'bezeichnung' => null, 'info' => 'artikel, artikelid, nummer, inaktiv, name_de, name_en, einheit, hersteller, herstellernummer, ean, artikelnummer_fremdnummern, kurztext_de, kurztext_en, anabregs_text, anabregs_text_en, beschreibung_de, beschreibung_en, uebersicht_de, uebersicht_en, herkunftsland, texteuebertragen, metadescription_de, metadescription_en, metakeywords_de, metakeywords_en, metatitle_de, metatitle_en, links_de, altersfreigabe, links_en, startseite_de, startseite_en, restmenge, startseite, standardbild, herstellerlink, lieferzeit, lieferzeitmanuell, gewicht, laenge, breite, hoehe, wichtig, porto, gesperrt, sperrgrund, gueltigbis, umsatzsteuer, ausverkauft, variante, variante_von_id, variantevon, pseudopreis, keinrabatterlaubt, einkaufspreis, pseudolager, downloadartikel, zolltarifnummer, freifeld_Kategorie, typ, kategoriename, steuer_art_produkt, steuer_art_produkt_download, anzahl_bilder, anzahl_lager, lagerkorrekturwert, autolagerlampe, waehrung, preis, steuersatz, bruttopreis, checksum, variantevorhanden' ] ] ]; return($einstellungen); } public function getKonfig($shopid, $data) { $this->shopid = $shopid; $this->data = $data; $importerSettings = $this->app->DB->SelectArr("SELECT `einstellungen_json` FROM `shopexport` WHERE `id` = '$shopid' LIMIT 1"); $importerSettings = reset($importerSettings); $einstellungen = []; if (!empty($importerSettings['einstellungen_json'])) { $einstellungen = json_decode($importerSettings['einstellungen_json'], true); } $this->protocol = $einstellungen['felder']['protokoll']; $this->apiKey = $einstellungen['felder']['apikey']; $this->shopUrl = rtrim($einstellungen['felder']['shopurl'], '/') . '/'; $this->mirakl_shopid = $einstellungen['felder']['mirakl_shopid']; if ($einstellungen['felder']['autoerstellehersteller'] === '1') { $this->createManufacturerAllowed = true; } $this->idsabholen = $einstellungen['felder']['abholen']; $this->idbearbeitung = $einstellungen['felder']['bearbeitung']; $this->idabgeschlossen = $einstellungen['felder']['abgeschlossen']; $query = sprintf('SELECT `steuerfreilieferlandexport` FROM `shopexport` WHERE `id` = %d', $this->shopid); $this->taxationByDestinationCountry = !empty($this->app->DB->Select($query)); $this->category_identifier = array($einstellungen['felder']['category_identifier_source'] => $einstellungen['felder']['category_identifier_source_value']); $this->create_products = $einstellungen['felder']['create_products']; $this->mirakl_error_text_product_missing = $einstellungen['felder']['mirakl_error_text_product_missing']; $this->offer_field_map = json_decode($einstellungen['felder']['offer_field_map'], true, flags: JSON_THROW_ON_ERROR); $this->product_field_map = json_decode($einstellungen['felder']['product_field_map'], true, flags: JSON_THROW_ON_ERROR); } private function miraklRequest(string $endpoint, $postdata = null, array $getdata = null, string $content_type = null, bool $raw = false, $debug = false, $debugurl = null) { $ch = curl_init(); $url_addition = ""; $headers = array("Authorization: " . $this->apiKey); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); if (!empty($this->mirakl_shopid)) { $getdata['shop_id'] = $this->mirakl_shopid; } if (!empty($getdata)) { $url_addition = "?"; $ampersand = ""; foreach ($getdata as $key => $value) { $url_addition .= $ampersand . $key . "=" . $value; $ampersand = "&"; } } if (!empty($postdata)) { curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); $headers[] = 'Content-Type: ' . $content_type; } if ($debugurl) { $url = $debugurl; } else { $url = $this->shopUrl; } curl_setopt($ch, CURLOPT_URL, $url . $endpoint . $url_addition); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLINFO_HEADER_OUT, true); curl_setopt($ch, CURLOPT_VERBOSE, true); $response = curl_exec($ch); if (curl_error($ch)) { $this->error[] = curl_error($ch); } curl_close($ch); $information = curl_getinfo($ch); if ($debug) { print_r($information); print_r($postdata); print_r($response); exit(); } if ($raw) return $response; return simplexml_load_string($response); } public function ImportAuth() { $ch = curl_init($this->shopUrl . "version"); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: " . $this->apiKey)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); if ($code == 200) { return 'success ' . print_r($response, true); } return $response; } /* * Fetches article list from the shop, puts them into table shopexport_getarticles, starts the prozessstarter getarticles which fetches details for each article via ImportGetArticle() */ public function ImportGetArticleList() { $result = []; $response = $this->miraklRequest('offers', raw: true); $result_array = json_decode($response); foreach ($result_array->offers as $offer) { $result[] = $offer->shop_sku; } array_unique($result); return $result; } /* * Fetches article details from the shop */ public function ImportGetArticle() { $articleList = $this->CatchRemoteCommand('data'); $parameters = array('product_references' => 'productID', 'product_'); $response = $this->miraklRequest('products?', raw: true); throw new Exception("Not implemented"); } /* * Gets a flexible mapped fieldvalue from feld, wert or eigenschaft */ public function GetFieldValue($article, $field_map_entry) { foreach ($field_map_entry as $key => $value) { switch ($key) { case 'feld': if (isset($article[$value])) { return($article[$value]); } else { throw new Exception("Artikelfeld existiert nicht: \"".$value."\""); } break; case 'freifeld': if (isset($article['freifelder']['DE'][$value])) { return($article['freifelder']['DE'][$value]); } else { throw new Exception("Freifeld existiert nicht: \"".$value."\""); } break; case 'eigenschaft': $sql = "SELECT wert FROM artikeleigenschaften ae INNER JOIN artikeleigenschaftenwerte aew ON aew.artikeleigenschaften = ae.id WHERE aew.artikel = '".$article['artikelid']."' AND ae.name = '".$value."' LIMIT 1"; return($this->app->DB->Select($sql)); break; case 'wert': return($value); break; } } return(null); } public function ImportSendListLager() { return($this->ImportSendList()); } /* * Send articles to shop */ public function ImportSendList() { $articleList = $this->CatchRemoteCommand('data'); $offer_export_result = $this->mirakl_export_offers($articleList); if ($offer_export_result['returncode'] == 0) { return(array('status' => true, 'message' => "Angebotsimport in Mirakl ok")); } // Check for missing products and try to create if ($this->create_products) { $create_products_list = array(); foreach ($offer_export_result['articleList'] as $key => $article) { if ($article['mirakl_export_offers_result']['returncode'] == 12) { switch ($article['mirakl_export_offers_result']['message']) { case $this->mirakl_error_text_product_missing: $create_products_list[] = $article; break; } } } if (empty($create_products_list)) { return(array('status' => false, 'message' => "Produktimport nicht möglich")); } $create_products_result = $this->mirakl_create_products($create_products_list); if ($create_products_result['returncode'] != 0) { $this->Log("Produktimport in Mirakl hat Fehler", print_r($create_products_result, true)); return(array('status' => false, 'message' => "Produktimport in Mirakl hat Fehler")); } // Retry offer import $offer_export_result = $this->mirakl_export_offers($articleList); if ($offer_export_result['returncode'] == 0) { return(array('status' => true, 'message' => "Angebots und Produktimport in Mirakl ok")); } } $this->Log("Angebotsimport in Mirakl hat Fehler", print_r($offer_export_result, true)); return(array('status' => false, 'message' => "Angebotsimport in Mirakl hat Fehler")); } private function getOrdersToProcess(int $limit) { } private function Log($message, $dump = '') { if ($this->protocol) { $this->app->erp->Logfile('Mirakl (Shop '.$this->shopid.') '.$message, print_r($dump, true)); } } public function ImportDeleteAuftrag() { } public function ImportUpdateAuftrag() { } public function ImportGetAuftraegeAnzahl() { } public function ImportGetAuftrag() { } /* * Send offer data to mirakl * $articleList = $this->CatchRemoteCommand('data'); * Return * array (returncode, message, articleList) articleList with added mirakl_export_offers_result element (array (returncode, message)) for further processing (e.g. create product) * returncode 0 = ok, 1 = not ok * returncode articleList 0 = ok, 10 = missing required attributes, 11 category not found, 12 rejected from mirakl */ private function mirakl_export_offers(array $articleList) : array { $mirakl_export_offers_return_value = array(); $mirakl_export_offers_return_value['returncode'] = 0; $mirakl_export_offers_return_value['articleList'] = array(); $this->Log('Angebotsexport start', print_r($articleList,true)); // First gather all articles as offers and send them // Wait for import to finish // Evaluate import foreach ($articleList as $key => $article) { $skip_article = false; /* * Export offer */ $category_found = false; $additional_fields = array(); $offer_for_mirakl = array( 'state_code' => '11', // ?!?! 'update_delete' => null // Update delete flag. Could be empty (means "update"), "update" or "delete". ); $kategorie = $this->GetFieldValue($article, $this->category_identifier); foreach ($this->offer_field_map as $offer_field_entry) { if ($offer_field_entry['kategorien'] != null) { if (!in_array($kategorie,$offer_field_entry['kategorien'])) { continue; } } $category_found = true; // Check required attributes $required = [ 'product_id_type', 'product_id', 'shop_sku', 'price' ]; $missing = null; foreach ($required as $key) { if (!isset($offer_field_entry['felder'][$key])) { $missing[] = $key; } } if ($missing) { $mirakl_export_offers_return_value['returncode'] = 1; $article['mirakl_export_offers_result'] = array('returncode' => 10, 'message' => "Pflichtfelder fehlen in Angebotskonfiguration von Kategorie \"".$offer_field_entry['kategorie']."\": ".implode(', ',$missing)); $mirakl_export_offers_return_value['articleList'][] = $article; $skip_article = true; } // Check Required attributes foreach ($offer_field_entry['felder'] as $offer_field => $offer_field_source) { if (!is_array($offer_field_source)) { $offer_field_source = array('feld' => $offer_field_source); } $offer_field_value = null; $is_additional_field = false; $offer_field_value = $this->GetFieldValue($article, $offer_field_source); if (in_array('zusatzfeld', $offer_field_source)) { $is_additional_field = true; } if ($is_additional_field) { $additional_field = array ( "code" => $offer_field, "value" => $offer_field_value ); $additional_fields[] = $additional_field; } else { $offer_for_mirakl[$offer_field] = $offer_field_value; } } } if ($skip_article) { continue; } if (!$category_found) { $mirakl_export_offers_return_value['returncode'] = 1; $article['mirakl_export_offers_result'] = array('returncode' => 11, 'message' => "Angebotskonfiguration für Artikel ".$article['nummer'].", Kategorie \"".$kategorie."\" nicht gefunden"); $mirakl_export_offers_return_value['articleList'][] = $article; continue; } if (!empty($additional_fields)) { $offer_for_mirakl['offer_additional_fields'] = $additional_fields; } $offers_for_mirakl[] = $offer_for_mirakl; $article['mirakl_export_offers_result'] = array('returncode' => 0, 'message' => ""); $mirakl_export_offers_return_value['articleList'][] = $article; } if (empty($offers_for_mirakl)) { $mirakl_export_offers_return_value['returncode'] = 1; $this->Log('Angebotsexport keine Artikel bereit', $mirakl_export_offers_return_value); $mirakl_export_offers_return_value['message'] = "Angebotsexport keine Artikel bereit"; return($mirakl_export_offers_return_value); } $data_for_mirakl = array(); $data_for_mirakl['offers'] = $offers_for_mirakl; $json_for_mirakl = json_encode($data_for_mirakl); $this->Log('Angebotsexport Daten', $json_for_mirakl); $result = []; $response = $this->miraklRequest('offers', postdata: $json_for_mirakl, content_type: 'application/json', raw: true); $result = json_decode($response); if (!isset($result->import_id)) { $mirakl_export_offers_return_value['returncode'] = 1; $this->Log('Angebotsimport abgelehnt', print_r($response,true)); $mirakl_export_offers_return_value['message'] = "Angebotsimport abgelehnt: ".print_r($response,true); return($mirakl_export_offers_return_value); } $this->Log('Angebotsimport angelegt', print_r($response,true)); $import_id = $result->import_id; // Wait for import to finish $status = null; /* WAITING_SYNCHRONIZATION_PRODUCT, WAITING, RUNNING, COMPLETE, FAILED */ while ($status != 'COMPLETE' && $status != 'FAILED') { sleep(5); $response = $this->miraklRequest('offers/imports/'.$import_id, raw: true); $result = json_decode($response); $status = $result->status; } if ($status == 'FAILED') { $this->Log('Angebotsimport fehlgeschlagen', print_r($response,true)); $mirakl_export_offers_return_value['returncode'] = 2; $mirakl_export_offers_return_value['message'] = "Angebotsimport fehlgeschlagen: ".print_r($response,true); return($mirakl_export_offers_return_value); } if ($result->lines_in_error == 0) { $this->Log('Angebotsimport ok', print_r($response,true)); return($mirakl_export_offers_return_value); } $this->Log('Angebotsimport meldet Fehler in '.$result->lines_in_error.' Zeilen', print_r($response,true)); $result = array(); // Check errors with CSV unfucking... $response = $this->miraklRequest('offers/imports/'.$import_id.'/error_report', raw: true); $response_lines = preg_split('/\R/', $response, flags: PREG_SPLIT_NO_EMPTY); $error_message_key = null; $firstline = true; foreach ($response_lines as $key => $response_line) { $response_array = str_getcsv($response_line,';','"'); if ($firstline) { $error_message_key = array_search("error-message",$response_array); $firstline = false; continue; } $article_key = array_search( $response_array['product_id'], array_column( $mirakl_export_offers_return_value['articleList'], 'product_id') ); $mirakl_export_offers_return_value['articleList'][$article_key]['mirakl_export_offers_result'] = array('returncode' => 12, 'message' => $response_array[$error_message_key]); } $this->Log('Angebotsimport Fehlerbericht', print_r($response,true)); $mirakl_export_offers_return_value['returncode'] = 1; return($mirakl_export_offers_return_value); } /* * Create products * Return * array (returncode, message, articleList) articleList with added mirakl_export_offers_result element (array (returncode, message)) for further processing (e.g. create product) * returncode 0 = ok, 1 = not ok * returncode articleList 0 = ok, 20 rejected from mirakl */ private function mirakl_create_products(array $articleList) : array { $mirakl_create_products_return_value = array(); $mirakl_create_products_return_value['returncode'] = 0; $mirakl_create_products_return_value['articleList'] = $articleList; // Build CSV $csv_header = ""; $newline = ""; foreach ($articleList as $article) { // Try to create the product $product_for_mirakl = array(); foreach ($this->product_field_map as $product_field_entry) { foreach ($product_field_entry['felder'] as $product_field => $product_field_source) { if (!is_array($product_field_source)) { $product_field_source = array('feld' => $product_field_source); } $product_field_value = null; $product_field_value = $this->GetFieldValue($article, $product_field_source); $product_for_mirakl[$product_field] = $product_field_value; } } // Create CSV from array if (empty($csv_header)) { $csv_header .= '"'.implode('";"',array_keys($product_for_mirakl)).'"'; } $csv .= $newline.'"'.implode('";"',$product_for_mirakl).'"'; $newline = "\r\n"; } $csv = $csv_header.$newline.$csv; $result = []; $this->Log('Produktexport Daten', print_r($csv,true)); $postdata = array('file' => new CURLStringFile(postname: 'import.csv', data: $csv)); $response = $this->miraklRequest('products/imports', postdata: $postdata, content_type: 'multipart/form-data', raw: true); $result = json_decode($response); if (!isset($result->import_id)) { $this->Log('Produktimport abgelehnt', print_r($response,true)); $mirakl_create_products_return_value['returncode'] = 1; return($mirakl_create_products_return_value); } $this->Log('Produktimport angelegt', print_r($result,true)); $import_id = $result->import_id; // Wait for import to finish $status = null; /* WAITING_SYNCHRONIZATION_PRODUCT, WAITING, RUNNING, COMPLETE, FAILED */ while ($status != 'COMPLETE' && $status != 'FAILED') { sleep(5); $response = $this->miraklRequest('products/imports/'.$import_id, raw: true); $result = json_decode($response); $status = $result->import_status; } if ($status == 'FAILED') { $this->Log('Produktimport fehlgeschlagen', print_r($response,true)); $mirakl_create_products_return_value['returncode'] = 1; return($mirakl_create_products_return_value); } if (!$result->has_error_report && !$result->has_transformation_error_report) { $this->Log('Produktimport ok', print_r($response,true)); } else { $this->Log('Produktimport meldet Fehler', print_r($response,true)); $mirakl_create_products_return_value['returncode'] = 1; } if ($result->has_new_product_report) { $response = $this->miraklRequest('products/imports/'.$import_id.'/new_product_report', raw: true); $this->Log('Produktimport "Hinzugefügte Produkte"-Bericht', print_r($response,true)); } if ($result->has_transformed_file) { $response = $this->miraklRequest('products/imports/'.$import_id.'/transformed_file', raw: true); $this->Log('Produktimport Datei im Marketplace-Format', print_r($response,true)); } if ($result->has_error_report) { // Check errors with CSV unfucking... $response = $this->miraklRequest('products/imports/'.$import_id.'/error_report', raw: true); $response_lines = preg_split('/\R/', $response, flags: PREG_SPLIT_NO_EMPTY); $error_message_key = null; $firstline = true; foreach ($response_lines as $key => $response_line) { $response_array = str_getcsv($response_line,';','"'); if ($firstline) { $error_message_key = array_search("ERRORS",$response_array); $firstline = false; continue; } $article_key = array_search( $response_array['product_id'], array_column( $mirakl_create_products_return_value['articleList'], 'product_id') ); $mirakl_create_products_return_value['articleList'][$article_key]['mirakl_create_products_result'] = array('returncode' => 13, 'message' => $response_array[$error_message_key]); } $this->Log('Produktimport Fehlerbericht', print_r($response,true)); } if ($result->has_transformation_error_report) { // Check errors with CSV unfucking... $response = $this->miraklRequest('products/imports/'.$import_id.'/transformation_error_report', raw: true); $response_lines = preg_split('/\R/', $response, flags: PREG_SPLIT_NO_EMPTY); $error_message_key = null; $firstline = true; foreach ($response_lines as $key => $response_line) { $response_array = str_getcsv($response_line,';','"'); if ($firstline) { $error_message_key = array_search("errors",$response_array); $firstline = false; continue; } $article_key = array_search( $response_array['product_id'], array_column( $mirakl_create_products_return_value['articleList'], 'product_id') ); $mirakl_create_products_return_value['articleList'][$article_key]['mirakl_create_products_result'] = array('returncode' => 14, 'message' => $response_array[$error_message_key]); } $this->Log('Produktimport Transformation-Fehlerbericht', print_r($response,true)); } return($mirakl_create_products_return_value); } }