cancel
Showing results for 
Search instead for 
Did you mean: 

Magento2: Data Model Interfaces/Classes to cope with nested arrays

Magento2: Data Model Interfaces/Classes to cope with nested arrays

Hi,

I'm trying to write a web service that can receive XML data from our Product Management system, below is a very basic example of some XML that I am struggling with. In the XML the category element can be in there multiple times and each category element can contain multiple product elements.
At the moment when I upload this to my web service, ServiceInputProcessor->_createFromArray is throwing an exception because it isn't realising that product is an array (I think!). Clearly I am not defining the getter/setter for the Product array correctly in the CategoryInterface - what am I doing wrong? Here's the example xml and classes:

 

<?xml version="1.0" encoding="UTF-8"?>
<agilityExport>
  <agilityExport>
    <category>
      <agilityId>55567</agilityId>
      <name>BBEP131</name>
      <product>
         <agilityId>55567</agilityId>
         <productSku>BBEP131</productSku>
         <salesCategory>Trousers</salesCategory>

      </product>
    </category>
  </agilityExport>
</agilityExport>

 

Here's my ExportInterface (for <agilityExport>)

<?php

namespace Agility\Import\Api\Data;

interface ExportInterface
{
/**
* getName
*
* @return string
*/
public function getName();

/**
* setName
*
* @param string $name
* @return $this
*/
public function setName($name);

/**
* getId
*
* @return string
*/
public function getId();

/**
* setId
*
* @param string $id
* @return $this
*/
public function setId($id);

/**
* getCategory
*
* @return Agility\Import\Api\Data\CategoryInterface[]
*/
public function getCategory();

/**
* setCategory
*
* @param Agility\Import\Api\Data\CategoryInterface[] $category
* @return $this
*/
public function setCategory($category);

/**
*
* @api
* @return Agility\Import\Api\Data\ProducInterface[]
*/
public function getProduct();

/**
*
* @api
* @param Agility\Import\Api\Data\ProducInterface[] $product
* @return $this
*/
public function setProduct($product);
}
?>

My Export.php based on that:

<?php

namespace Agility\Import\Model;

use Agility\Import\Api\Data\ExportInterface as ExportInterface;

class Export extends \Magento\Framework\Model\AbstractModel implements ExportInterface
{
/*
* @var string
*/
protected $obj_name;

/*
* @var string
*/
protected $obj_id;

/*
* @var Agility\Import\Model\ResourceModel\Category[]
*/
protected $category;

/*
* @var Agility\Import\Model\ResourceModel\Product[]
*/
protected $product;


public function __construct() {
return $this;
}

public function getName() {
return $this->obj_name;
}

public function setName($name) {
$this->obj_name = $name;
return $this;
}

public function getId() {
return $this->obj_id;
}

public function setId($id) {
$this->obj_id = $id;
return $this;
}

public function getCategory() {
return $this->category;
}

public function setCategory($category) {
$this->category = $category;

return $this;
}

/**
*
* @api
* @return Agility\Import\Model\ResourceModel\Product[]
*/
public function getProduct(){
return $this->product;
}

/**
*
* @api
* @param Agility\Import\Model\ResourceModel\Product[] $product
* @return $this
*/
public function setProduct($product){
$this->product = $product;
return $this;
}
}
?>

My CategoryInterface.php:
<?php

namespace Agility\Import\Api\Data;

interface CategoryInterface
{

/**
*
* @api
* @return string
*/
public function getName();

/**
*
* @api
* @param string $name
* @return $this
*/
public function setName($name);

/**
*
* @api
* @return string
*/
public function getAgilityId();

/**
*
* @api
* @param string $agilityId
* @return $this
*/
public function setAgilityId($agilityId);

/**
*
* @api
* @return Agility\Import\Api\Data\ProducInterface[]
*/
public function getProduct();

/**
*
* @api
* @param Agility\Import\Api\Data\ProducInterface[] $product
* @return $this
*/
public function setProduct($product);
}
?>

My Category.php based on that:
<?php

namespace Agility\Import\Model\Data;

use Agility\Import\Api\Data\CategoryInterface;

class Category extends \Magento\Framework\Model\AbstractModel implements CategoryInterface
{
/*
* @var string
*/
protected $name;

/*
* @var string
*/
protected $agilityId;

/*
* @var Agility\Import\Api\Data\CategoryInterface[]
*/
protected $category;

/*
* @var Agility\Import\Api\Data\ProductInterface[]
*/
protected $product;


public function __construct() {
return $this;
}

/**
*
* @api
* @return string
*/
public function getName() {
return $this->name;
}

/**
*
* @api
* @param string $name
* @return $this
*/
public function setName($name) {
$this->name = $name;
return $this;
}

/**
*
* @api
* @return string
*/
public function getAgilityId() {
return $this->agilityId;
}

/**
*
* @api
* @param string $id
* @return $this
*/
public function setAgilityId($agilityId) {
$this->agilityId = $agilityId;
return $this;
}

/**
*
* @api
* @return Agility\Import\Api\Data\ProductInterface[]
*/
public function getProduct(){
return $this->product;
}

/**
*
* @api
* @param Agility\Import\Api\Data\ProductInterface[] $product
* @return $this
*/
public function setProduct($product){
$this->product = $product;
return $this;
}
}
?>

Thanks,
Dan Tate

 

2 REPLIES

Re: Magento2: Data Model Interfaces/Classes to cope with nested arrays

You can parse the XML manually using the standard SimpleXML class.

Re: Magento2: Data Model Interfaces/Classes to cope with nested arrays

That would be good - how do you bypass Magento parsing it automatically?

 

I managed to get around the nested arrays, but if there is only one element in the array then the deserializer doesn't put it into a 1-element array, instead it just makes that element into a node.  If I could bypass the Magento parser, that would be really helpful!

 

Thanks,

Dan