Plugin Directory

Changeset 3028087


Ignore:
Timestamp:
01/29/2024 09:03:29 AM (2 years ago)
Author:
outshifter
Message:

update just send items payload

Location:
outshifter-export/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • outshifter-export/trunk/README.txt

    r3022907 r3028087  
    44Requires at least: 5.0
    55Tested up to: 6.4.2
    6 Stable tag: 3.6
     6Stable tag: 3.8
    77Requires PHP: 7.0
    88License: GPLv3
  • outshifter-export/trunk/index.php

    r3008650 r3028087  
    88 * Author: Reachu
    99 * Author URI: https://reachu.io/
    10  * Version: 3.6
     10 * Version: 3.8
    1111 */
    1212
     
    348348      }
    349349      $attachment_ids = $product->get_gallery_image_ids();
     350      self::log("Fetched attachment IDs: " . implode(', ', $attachment_ids));
    350351      foreach ($attachment_ids as $attachment_id) {
     352        self::log("Processing attachment ID: " . $attachment_id);
    351353        $image_url = '';
    352         if ($image_id) {
     354        if ($attachment_id) {
    353355          $image_url = wp_get_attachment_image_url($attachment_id, 'full');
    354356          $attachment_url_https = self::forceSecureImage($image_url);
    355357          $images[] = array('order' => $order, "image" => $attachment_url_https);
     358          self::log("Added image URL: " . $attachment_url_https);
    356359          $order++;
     360        } else {
     361          self::log("No attachment ID found.");
    357362        }
    358363      }
     
    485490    }
    486491
    487     public static function reachu_update_product($post_id, $userApiKey)
    488     {
    489       self::log('[update_product] Handle update post ' . $post_id . ' by authentification: ' . $userApiKey);
    490       $reachuOrigin = get_post_meta($post_id, OSEWCPHJC_reachu_ORIGIN, true);
     492    private static function areOptionsEqual($currentOptions, $initialOptions) {
     493      $currentOptions = is_object($currentOptions) ? get_object_vars($currentOptions) : $currentOptions;
     494      $initialOptions = is_object($initialOptions) ? get_object_vars($initialOptions) : $initialOptions;
     495 
     496      if (count($currentOptions) != count($initialOptions)) {
     497        return false;
     498      }
     499 
     500      foreach ($currentOptions as $index => $currentOption) {
     501        $currentOption = is_object($currentOption) ? get_object_vars($currentOption) : $currentOption;
     502       
     503        if (!isset($initialOptions[$index])) {
     504          return false;
     505        }
     506
     507        $initialOption = is_object($initialOptions[$index]) ? get_object_vars($initialOptions[$index]) : $initialOptions[$index];
     508
     509        $currentValues = is_array($currentOption['values']) ? implode(',', $currentOption['values']) : $currentOption['values'];
     510        $initialValues = is_array($initialOption['values']) ? implode(',', $initialOption['values']) : $initialOption['values'];
     511
     512        if ($currentOption['name'] !== $initialOption['name'] ||
     513          $currentOption['order'] !== $initialOption['order'] ||
     514          $currentValues !== $initialValues) {
     515          return false;
     516        }
     517      }
     518 
     519      return true;
     520    }
     521
     522    private static function isMainPriceChanged($currentPrice, $originalPrice) {
     523      $currentPrice = is_object($currentPrice) ? get_object_vars($currentPrice) : $currentPrice;
     524      $originalPrice = is_object($originalPrice) ? get_object_vars($originalPrice) : $originalPrice;
     525 
     526      $floatTolerance = 0.01;
     527 
     528      $currencyCodeMatches = isset($currentPrice['currencyCode'], $originalPrice['currencyCode']) &&
     529                              $currentPrice['currencyCode'] === $originalPrice['currencyCode'];
     530 
     531      if (!$currencyCodeMatches) {
     532          self::log("Currency codes do not match.");
     533          return ['amountChanged' => false, 'compareAtChanged' => false];
     534      }
     535 
     536      $amountChanged = isset($currentPrice['amount'], $originalPrice['amount']) &&
     537                       abs(floatval($currentPrice['amount']) - floatval($originalPrice['amount'])) > $floatTolerance;
     538 
     539      $compareAtChanged = isset($currentPrice['compareAt'], $originalPrice['compareAt']) &&
     540                          abs(floatval($currentPrice['compareAt']) - floatval($originalPrice['compareAt'])) > $floatTolerance;
     541 
     542      return ['amountChanged' => $amountChanged, 'compareAtChanged' => $compareAtChanged];
     543    }
     544
     545    private static function getChangedValues($currentValues, $initialValues) {
     546      $changes = [];
     547      $initialValuesArray = is_object($initialValues) ? get_object_vars($initialValues) : $initialValues;
     548
     549      foreach ($currentValues as $key => $currentValue) {
     550        if (!array_key_exists($key, $initialValuesArray)) {
     551          $changes[$key] = $currentValue;
     552          continue;
     553        }
     554
     555        $initialValue = $initialValuesArray[$key];
     556
     557        if ($key === 'variants') {
     558          $variantChanges = self::compareVariants($currentValue, $initialValue);
     559          if (!empty($variantChanges)) {
     560            $changes[$key] = $variantChanges;
     561          }
     562        } elseif ($key === 'images') {
     563          $imageChanges = self::compareImages($currentValue, $initialValue);
     564          if (!empty($imageChanges)) {
     565            $changes[$key] = $imageChanges;
     566          }
     567        } elseif ($key === 'options') {
     568          if (!self::areOptionsEqual($currentValue, $initialValue)) {
     569            $changes[$key] = $currentValue;
     570          }
     571        } elseif ($key === 'price') {
     572          $originalPrice = isset($initialValuesArray['originalPrice']) ? $initialValuesArray['originalPrice'] : null;
     573          $priceChange = self::isMainPriceChanged($currentValue, $originalPrice);
     574
     575          if ($priceChange['amountChanged'] || $priceChange['compareAtChanged']) {
     576            $priceUpdate = ['currencyCode' => $currentValue['currencyCode']];
     577            if ($priceChange['amountChanged']) {
     578              $priceUpdate['amount'] = $currentValue['amount'];
     579            }
     580            if ($priceChange['compareAtChanged']) {
     581              $priceUpdate['compareAt'] = $currentValue['compareAt'];
     582            }
     583            $changes[$key] = $priceUpdate;
     584          }
     585        } elseif (is_array($currentValue) && is_array($initialValue)) {
     586          $nestedChanges = self::getChangedValues($currentValue, $initialValue);
     587          if (!empty($nestedChanges)) {
     588            $changes[$key] = $nestedChanges;
     589          }
     590        } else if ($currentValue !== $initialValue) {
     591          $changes[$key] = $currentValue;
     592        }
     593      }
     594
     595      if (isset($changes['variants'])) {
     596        foreach ($changes['variants'] as &$variant) {
     597          if (isset($variant['images']) && is_array($variant['images'])) {
     598            foreach ($variant['images'] as &$image) {
     599              if (isset($image['image'])) {
     600                $image['url'] = $image['image'];
     601                //unset($image['image']);
     602              }
     603            }
     604          }
     605        }
     606      }
     607
     608      foreach (['originId', 'currency', 'from'] as $unnecessaryField) {
     609        if (array_key_exists($unnecessaryField, $changes)) {
     610          unset($changes[$unnecessaryField]);
     611        }
     612      }
     613
     614      return $changes;
     615    }
     616
     617    private static function compareImages($currentImages, $initialImages) {
     618      if (count($currentImages) != count($initialImages)) {
     619        return $currentImages;
     620      }
     621 
     622      foreach ($currentImages as $index => $currentImage) {
     623        $initialImage = $initialImages[$index] ?? null;
     624        if (!$initialImage || !self::isImageEqual($currentImage, $initialImage)) {
     625          return $currentImages;
     626        }
     627      }
     628 
     629      return [];
     630   }
     631 
     632 
     633    private static function isImageEqual($image1, $image2) {
     634      $image1 = is_object($image1) ? get_object_vars($image1) : $image1;
     635      $image2 = is_object($image2) ? get_object_vars($image2) : $image2;
     636 
     637      $url1 = $image1['image'] ?? $image1['url'] ?? '';
     638      $url2 = $image2['image'] ?? $image2['url'] ?? '';
     639
     640      if (empty($url1) || empty($url2)) {
     641        return true;
     642      }
     643 
     644      return $url1 === $url2;
     645    }
     646
     647    private static function compareVariants($wooVariants, $reachuVariants) {
     648      $changes = [];
     649      $variantChanged = false;
     650 
     651      foreach ($wooVariants as $index => $wooVariant) {
     652        $reachuVariant = self::findVariantById($reachuVariants, $wooVariant['originId'] ?? null);
     653
     654        if (!empty($wooVariant['images']) && is_array($wooVariant['images'])) {
     655          foreach ($wooVariant['images'] as $imgIndex => $imageData) {
     656            if (isset($imageData['image'])) {
     657              $wooVariant['images'][$imgIndex]['url'] = $imageData['image'];
     658              unset($wooVariant['images'][$imgIndex]['image']);
     659            }
     660          }
     661        }
     662
     663        if ($reachuVariant && self::isVariantChanged($wooVariant, $reachuVariant)) {
     664          $variantChanged = true;
     665          break;
     666        }
     667 
     668      }
     669 
     670      if ($variantChanged) {
     671        $changes = $wooVariants;
     672      }
     673 
     674      return $changes;
     675    }
     676 
     677
     678    private static function findVariantById($variants, $originId) {
     679      foreach ($variants as $variant) {
     680        $variant = is_object($variant) ? get_object_vars($variant) : $variant;
     681        if (isset($variant['originId']) && $variant['originId'] == $originId) {
     682          return $variant;
     683        }
     684      }
     685      return null;
     686    }
     687
     688    private static function isVariantChanged($wooVariant, $reachuVariant) {
     689      $wooVariant = is_object($wooVariant) ? get_object_vars($wooVariant) : $wooVariant;
     690      $reachuVariant = is_object($reachuVariant) ? get_object_vars($reachuVariant) : $reachuVariant;
     691 
     692      if (isset($reachuVariant['originalPrice']) && is_object($reachuVariant['originalPrice'])) {
     693        $reachuVariant['originalPrice'] = get_object_vars($reachuVariant['originalPrice']);
     694      }
     695      if (isset($reachuVariant['images'][0]) && is_object($reachuVariant['images'][0])) {
     696        $reachuVariant['images'][0] = get_object_vars($reachuVariant['images'][0]);
     697      }
     698 
     699      $floatTolerance = 0.01;
     700 
     701      $priceChanged = abs(floatval($wooVariant['price']) - floatval($reachuVariant['originalPrice']['amount'])) > $floatTolerance;
     702      $priceCompareAtChanged = abs(floatval($wooVariant['priceCompareAt']) - floatval($reachuVariant['originalPrice']['compareAt'])) > $floatTolerance;
     703      $quantityChanged = $wooVariant['quantity'] !== $reachuVariant['quantity'];
     704      $titleChanged = $wooVariant['title'] !== $reachuVariant['title'];
     705      $originIdChanged = (string)$wooVariant['originId'] !== (string)$reachuVariant['originId'];
     706      $imageChanged = !self::isImageEqual($wooVariant['images'][0] ?? [], $reachuVariant['images'][0] ?? []);
     707      $skuChanged = $wooVariant['sku'] !== $reachuVariant['sku'];
     708 
     709      if ($priceChanged || $priceCompareAtChanged || $quantityChanged || $titleChanged || $originIdChanged || $imageChanged || $skuChanged) {
     710        self::log("Variant change detected due to: " . implode(", ", array_filter([
     711          $priceChanged ? "Price" : null,
     712          $priceCompareAtChanged ? "PriceCompareAt" : null,
     713          $quantityChanged ? "Quantity" : null,
     714          $titleChanged ? "Title" : null,
     715          $originIdChanged ? "OriginId" : null,
     716          $imageChanged ? "Image" : null,
     717          $skuChanged ? "SKU" : null,
     718        ])));
     719        return true;
     720      }
     721 
     722      return false;
     723    }
     724 
     725    public static function reachu_update_product($post_id, $userApiKey) {
     726      self::log('[update_product] Handle update post ' . $post_id . ' by authentication: ' . $userApiKey);
     727      $reachuOrigin = get_post_meta($post_id, 'OSEWCPHJC_reachu_ORIGIN', true);
     728 
    491729      if ($reachuOrigin) {
    492         self::log('[update_product] No procesable. The product\'s origin is reachu ' . $reachuOrigin);
     730        self::log('[update_product] No processable. The product\'s origin is reachu ' . $reachuOrigin);
    493731      } else {
    494732        $reachuProductId = self::getProductId($userApiKey, $post_id);
    495         $postDto = self::buildProductDto($post_id);
     733        $currentWooData = self::buildProductDto($post_id);
     734 
    496735        if ($reachuProductId) {
    497736          $product = wc_get_product($post_id);
    498           if ($product->is_type('variable')) {
    499             $externalProduct = self::call('/api/products/' . $reachuProductId);
    500             if($externalProduct) {
    501               $externalProduct = (array) $externalProduct;
    502               $externalVariants = isset($externalProduct['variants']) ? (array) $externalProduct['variants'] : [];
    503               foreach($postDto['variants'] as &$variant) {
    504                 foreach($externalVariants as $externalVariant) {
    505                   $externalVariant = (array) $externalVariant;
    506                   if($variant['originId'] == $externalVariant['originId']) {
    507                     $variant['id'] = $externalVariant['id'];
    508                   }
     737          $currentReachuData = self::call('/api/products/' . $reachuProductId);
     738          $dataToUpdate = self::getChangedValues($currentWooData, $currentReachuData);
     739 
     740          if (isset($dataToUpdate['variants']) && $currentReachuData) {
     741            $externalVariants = isset($currentReachuData->variants) ? (array) $currentReachuData->variants : [];
     742            foreach ($dataToUpdate['variants'] as &$variant) {
     743              foreach ($externalVariants as $externalVariant) {
     744                $externalVariant = (array) $externalVariant;
     745                if ($variant['originId'] == $externalVariant['originId']) {
     746                  $variant['id'] = $externalVariant['id'];
    509747                }
    510748              }
    511               unset($variant);
    512             }
    513           }
    514           self::log('[add_update_product] Updating product ' . $reachuProductId . ' from post ' . $post_id . '...');
    515           $updated = self::call('/api/products/' . $reachuProductId, 'PUT', $postDto);
    516           if ($updated) {
    517             self::log('[add_update_product] Product ' . $reachuProductId . ' updated');
     749            }
     750            unset($variant);
     751          }
     752 
     753          if (!empty($dataToUpdate)) {
     754            self::log('[add_update_product] Updating product ' . $reachuProductId . ' from post ' . $post_id . '...');
     755            self::log('[add_update_product] Data to update for product 16:14' . $reachuProductId . ': ' . print_r($dataToUpdate, true));
     756            $updated = self::call('/api/products/' . $reachuProductId, 'PUT', $dataToUpdate);
     757            if ($updated) {
     758              self::log('[add_update_product] Product ' . $reachuProductId . ' updated with changed fields');
     759            } else {
     760              self::log('[add_update_product] Error updating product ' . $reachuProductId . ' from post ' . $post_id, 'error');
     761            }
    518762          } else {
    519             self::log('[add_update_product] Error updating product ' . $reachuProductId . ' from post ' . $post_id, 'error');
     763            self::log('[add_update_product] No changes detected for product ' . $reachuProductId . '. No update dispatched.');
    520764          }
    521765        }
     
    666910    public static function handle_save_product($postId)
    667911    {
     912      $userApiKey = self::getUserApiKey();
     913      if (empty($userApiKey)) {
     914        self::log("No API key found for Product {$postId}. Skipping sync.");
     915        return;
     916      }
     917      $reachuProductId = self::getProductId($userApiKey, $postId);
     918      $product = wc_get_product($postId);
     919      if ($reachuProductId && $product && $product->is_type('variable')) {
     920        sleep(2);
     921      }
     922      $updating_post_id = 'update_product_' . $postId;
    668923      $updating_post_id = 'update_product_' . $postId;
    669924      if (false === ($updating_post = get_transient($updating_post_id))) {
    670         $userApiKey = self::getUserApiKey();
    671         if (!empty($userApiKey)) {
    672925          self::reachu_update_product($postId, $userApiKey);
    673         } else {
    674           self::log("No API key found for Product {$postId}. Skipping sync.");
    675       }
    676         set_transient($updating_post_id, $postId, 5);
     926          set_transient($updating_post_id, $postId, 5);
    677927      }
    678928    }
Note: See TracChangeset for help on using the changeset viewer.