davidtsadler / ebay-sdk-php

An eBay SDK for PHP. Use the eBay API in your PHP projects.
Apache License 2.0
349 stars 341 forks source link

Serialize from/to json #243

Closed albertixcom closed 4 years ago

albertixcom commented 5 years ago

Hi all 1) Try to convert to json string remote item, ex: $string = json_encode($remoteItem->toArray(), JSON_PRETTY_PRINT); 2) Decode previously string to original object

  $data = json_decode($string, true);
  $item = new ItemType($data);

Conversion generate ERROR if some amounts is formatted like integer ex: "179"

{
    "BuyItNowPrice": {
        "value": 179,
        "currencyID": "EUR"
    },

This is my reverse solution:

/**
   * @param mixed $item
   * @param array $data
   * @throws \ReflectionException
   */
  public static function fromArray(&$item, $data) {
    $class = new \ReflectionClass($item);

    //
    // reverse engenering for private "$propertyTypes"
    //
    $classProps = [];

    $pattern = "/@(?=(.*)[ ]*(?:@|\r\n|\n))/U";
    preg_match_all($pattern, $class->getDocComment(), $matches);
    foreach($matches[1] as $rawParameter) {
      if(preg_match("/^property ([A-z0-9\_\-]+) (.*)$/", $rawParameter, $match)) {
        $paramName = substr($match[2],1);
        $paramType = $match[1];
        $classProps[$paramName] = $paramType;
      }
    }

    foreach ($data As $key => $value) {
      $type = $classProps[$key];

      // simple class name
      $name = basename(str_replace('\\', '/', $type));

      if ($name == 'DateTime') {
        $value = \DateTime::createFromFormat('Y-m-d\TH:i:s.000\Z', $value);
      }
      // this is complex type
      elseif (preg_match('/\\\\DTS/', $type)) {

        // if complex type is array
        if (preg_match('/(.*)\[\]$/', $type, $match)) {
          $_type = $match[1];
          $_classTypeArray = [];
          foreach ($value As $_value) {
            $_classType = new $_type();
            self::fromArray($_classType, $_value);
            $_classTypeArray[] = $_classType;
          }
          $classType = $_classTypeArray;
        } else {
          $classType = new $type();

          // this is simple class, so assign by hand
          if ($name == 'AmountType') {
            $classType->value = doubleval($value['value']);
            $classType->currencyID = $value['currencyID'];
          } else {
            self::fromArray($classType, $value);
          }
        }
        $value = $classType;
      }
      $item->$key = $value;
    }
  }

How to use:

    $data = json_decode(file_get_contents($file), true);
    $item = new ItemType();
    self::fromArray($item, $data);

... viola ! ITEM is perfectly reversed hope helps for somebody. Alberto