I am a junior web developer currently doing my first internship and I had a lot of freedom to solve small problems the way I thought was best. (There aren't really any developers here so I am completely on my own). My solution worked and is no longer needed, but I really want to improve and become a better programmer, so I wonder if anyone could tell me what I did wrong and how I should improve my code, or any advice in general.
Part of my mission was to transfer images associated to products (each product has an unique identifier) from one PIM (Product Information Manager) to another, and the only way to do so was through API calls. The products had already been copied from one PIM to another, so all that was left to do was copy the images. I had only learnt C, C++ and Java up to this point, so I decided I'd learn PHP to make these kinds of scripts, so apologies in advance for the beginner's work.
What the script does is :
Get authentication tokens from the ancient and new PIM.
Start a loop from
i
to 3600 (amount of products)Do an HTTP GET call to extract the ith product from the ancient PIM, decode the JSON file obtained containing all the product information (identifier, values, etc.) into a PHP multidimensional array.
Extract the identifier from the array and store it in a string variable.
Store every key associated to an image in the product values in an array
Check if this identifier exists in the new PIM, if so start a loop that iterates through every key value associated with an image, and checks if this key exists in the JSON file (some products have less images so the key doesn't even exist in the JSON).
If the key exists, do a GET call to download it then store it in a temp file.
Inject this temp file into the value of the key of the product of the new PIM.
Check for errors, unlink the temp image
Once every key image value of the product has been looped through, start the next product loop
There is also a time check mechanism I set in place because I need to refresh the tokens every hour.
<?php /* Fonctionnement du script : - Extraction des produits du PIM enexo 1 par 1, puis extraction des images des produits pour les injecter dans les produits identiques du nouveau PIM. */ $enexoTokenCurl = curl_init(); $v2TokenCurl = curl_init(); $enexoProductCurl = curl_init(); $v2ProductCurl = curl_init(); $enexoImageDL = curl_init(); $v2ImageInject = curl_init(); curl_setopt_array($enexoTokenCurl, array( CURLOPT_URL => 'https://ancient.api.address/', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => '{ "username" : "redacted", "password" : "redacted", "grant_type": "redacted" }', CURLOPT_HTTPHEADER => array( 'Content-Type: application/json', 'Authorization: Basic redacted', 'Cookie: BAPID=redacted' ), )); curl_setopt_array($v2TokenCurl, array( CURLOPT_URL => 'http://new.api.website/', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => '{ "username" : "redactoo", "password" : "redactoo", "grant_type": "redactoo" }', CURLOPT_HTTPHEADER => array( 'Content-Type: application/json', 'Authorization: Basic redactoo', 'Cookie: BAPID=redactoo' ), )); $multiHandle = curl_multi_init(); curl_multi_add_handle($multiHandle, $enexoTokenCurl); curl_multi_add_handle($multiHandle, $v2TokenCurl); $running = null; do { curl_multi_exec($multiHandle, $running); } while ($running); curl_multi_remove_handle($multiHandle, $enexoTokenCurl); curl_multi_remove_handle($multiHandle, $v2TokenCurl); curl_multi_close($multiHandle); $enexoResponse = curl_multi_getcontent($enexoTokenCurl); $enexoToken = (json_decode($enexoResponse))->access_token; $v2Response = curl_multi_getcontent($v2TokenCurl); $v2Token = (json_decode($v2Response))->access_token; // On store dans un tableau tous les attributs d'images existant dans le pim $imageTypeAttributes = ['PV1', 'PV2', 'PV3', 'PV4', 'PV5', 'PV6', 'PV7', 'PC1', 'MS1', 'MS2', 'MS3']; $last_time = microtime(true); // On va boucler les 3599 produits de l'ancien PIM et transferer les images de produit a produit vers le nouveau for ($page_num = 1611; $page_num < 3600; $page_num++) { // Recuperation du produit de la page actuelle (page_num) de l'ancien pim curl_setopt_array($enexoProductCurl, array( CURLOPT_URL => 'https://redaci.api' . $page_num . '&limit=1', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => array( 'Authorization: Bearer ' . $enexoToken, 'Cookie: BAPID=uc8igrpidb8dfcgqlf39uv2snn' ), )); // On decode le fichier JSON contenant les informations du produit $productJson = curl_exec($enexoProductCurl); $productAttributes = json_decode($productJson, true); // On recupere l'identifiant du produit importe et le tableau des valeurs d'attributs $identifier = $productAttributes['_embedded']['items'][0]['identifier']; // On remplace le caractere # contenu dans certains identifiants par %23 (solution d'echappement qui représente #) pour eviter que l'url API ne detecte le "#" comme fragment $hashtagID = str_replace('#', '%23', $identifier); // On rajoute les deux leading 0 qui sont supprimes par json_encode pour seulement ces deux nombres la. Bug etrange. if ($identifier === 1670 || $identifier === 1767) { $identifier = '00' . $identifier; } $values = $productAttributes['_embedded']['items'][0]['values']; $url = 'http://redacto.apo' . $hashtagID; curl_setopt_array($v2ProductCurl, array( CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => array( 'Authorization: Bearer ' . $v2Token, 'Cookie: BAPID=kq94lmha20s2ntlb181eau6nnr' ), )); $existsError = curl_exec($v2ProductCurl); if (str_contains($existsError, 'does not exist')) { echo 'Le produit ' . $identifier . ' n\'existe pas sur le nouveau PIM : ' . $existsError . "\n"; } else { foreach ($imageTypeAttributes as $imageAttribute) { // On verifie si l'attribut d'image dans la boucle actuelle existe pour le produit en cours de traitement if (array_key_exists($imageAttribute, $values) && array_key_exists("_links", $values[$imageAttribute][0])) { // On envoie un call API GET pour telecharger l'image stockee dans l'ancien pim correspondant a l'attribut dans la boucle actuelle curl_setopt_array($enexoImageDL, array( CURLOPT_URL => $values[$imageAttribute][0]['_links']["download"]['href'], CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => array( 'Authorization: Bearer ' . $enexoToken, 'Cookie: BAPID=hv6sup4d5uc1fokhhb2orj1tj4' ), )); // On stocke l'image temporairement dans un fichier qu'on va creer avec un nom de type "EAN du produit" + "nom de l'attribut" .jpg $imgUrl = "tempImage/" . $values["EAN"][0]["data"] . $imageAttribute . '.jpg'; $fp = fopen($imgUrl, 'x'); fwrite($fp, curl_exec($enexoImageDL)); fclose($fp); // On injecte l'image vers l'attribut du produit sur le nouveau pim curl_setopt_array($v2ImageInject, array( CURLOPT_URL => 'http://redictucho.del.apioucho', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', // On renseigne l'identifiant et l'attribut du produit qui sont identiques sur l'ancien et le nouveau pim, ce qui permet de transferer l'image au bon produit. CURLOPT_POSTFIELDS => array('product' => '{"identifier":"' . $identifier . '", "attribute":"' . $imageAttribute . '", "scope": null,"locale":null}', 'file' => new CURLFILE($imgUrl)), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer ' . $v2Token, 'Content-Type: multipart/form-data', 'Cookie: BAPID=vb820vi7ec4umcmhu9n5p18p60' ), )); $error = curl_exec($v2ImageInject); if ($error) { echo '!!! ERROR !!! ' . $error . " !!! ERROR !!!\n"; } else { echo 'Product n°' . $identifier . ' - Image upload worked for ' . $imageAttribute . "\n"; } // On supprime le fichier d'image temporaire dont on n'a plus besoin unlink($imgUrl); } } } echo $page_num . ' - ' . $identifier . " DONE\n\n"; $check_time = microtime(true)-$last_time; if ($check_time > 3500) { $enexoResponse = curl_multi_getcontent($enexoTokenCurl); $enexoToken = (json_decode($enexoResponse))->access_token; $v2Response = curl_multi_getcontent($v2TokenCurl); $v2Token = (json_decode($v2Response))->access_token; $last_time = microtime(true); } } curl_close($enexoTokenCurl); curl_close($v2TokenCurl); curl_close($enexoProductCurl); curl_close($v2ProductCurl); curl_close($enexoImageDL); curl_close($v2ImageInject);