I'm trying to return a collection of the products that meets an input criteria using Magento api2. Everything is working as expected other than how Magento formats the final JSON.
What i basically want to do is to return a json with two keys, one is the totalRecords specifying the number of items without the sorting (so I can handle the paging on the client side), and the items as the actual products. So I made the below tries:
1. First Try
The problem I faced here is that i found Magento for some reason always return the first item in the Items key, so I get the right totalRecords and the right first item, but i'm not sure what kind of post processing Magento does on the output to stripe the other elements of the array.
protected function _retrieveCollection()
{
$store_id = $this->getRequest()->getParam('store_id');
$page_size = $this->getRequest()->getParam('page_size');
$page = $this->getRequest()->getParam('page');
/** @var $collection Mage_Catalog_Model_Resource_Product_Collection */
$collection = Mage::getResourceModel('catalog/product_collection');
$collection->setStoreId($store_id);
$collection->addAttributeToSelect(array_keys(
$this->getAvailableAttributes($this->getUserType(), Mage_Api2_Model_Resource::OPERATION_ATTRIBUTE_READ)
));
$collection->addFinalPrice();
if ($page_size) $collection->setPageSize($page_size);
if ($page) $collection->setCurPage($page);
$this->_applyCategoryFilter($collection);
$this->_applyCollectionModifiers($collection);
$products = $collection->load()->toArray();
return array(
'items' => array_values($products),
'totalRecords' => $collection->getSize()
);
}
2. Second Try
The second try was simply using the Varien_Data_Collection. It returns all the items, however the totalRecords will be incorrect, since im just copying the results from the products collection to this new collection, which is obviously not the right approach.
protected function _retrieveCollection()
{
$store_id = $this->getRequest()->getParam('store_id');
$page_size = $this->getRequest()->getParam('page_size');
$page = $this->getRequest()->getParam('page');
/** @var $collection Mage_Catalog_Model_Resource_Product_Collection */
$collection = Mage::getResourceModel('catalog/product_collection');
$collection->setStoreId($store_id);
$collection->addAttributeToSelect(array_keys(
$this->getAvailableAttributes($this->getUserType(), Mage_Api2_Model_Resource::OPERATION_ATTRIBUTE_READ)
));
$collection->addFinalPrice();
if ($page_size) $collection->setPageSize($page_size);
if ($page) $collection->setCurPage($page);
$this->_applyCategoryFilter($collection);
$this->_applyCollectionModifiers($collection);
$products = $collection->load()->toArray();
$varien_collection = new Varien_Data_Collection();
foreach ($products as $key => $value) {
$varien_object = new Varien_Object();
$varien_object->setData($value);
$varien_collection->addItem($varien_object);
}
return $varien_collection;
}
I think my first try was using the right approach, however i have no clue on why Magento is stripping the other items in the Items array.
Update #1
After a small discussion with @DigitalPianism, I was thinking there is a problem with the JSON breaking the Magento formatting, however when i try returning something as simple as this:
return array(
'items' => array(array('r' => 'q'), array('b' => 'f')),
'totalRecords' => $collection->getSize()
);
only the first item is returned as well, and with the lack of documentation i have no idea why the first array is only returned.
Update #2
Problem is in nested array, outlined here https://magento.stackexchange.com/a/33012/13103, not sure how i should return it now :(
Update #3
So digging in how Magento formats the output, i opened /app/code/core/Mage/Api2/Model/Resource.php as suggested by @DigtialPianisim, to line 243 (Magento 1.9), specifically this block:
case self::ACTION_TYPE_COLLECTION . self::OPERATION_RETRIEVE:
$this->_errorIfMethodNotExist('_retrieveCollection');
$retrievedData = $this->_retrieveCollection();
$filteredData = $this->getFilter()->collectionOut($retrievedData);
$this->_render($filteredData);
break;
The problem is what this line does to the output $this->getFilter()->collectionOut($retrievedData);, if i just replace the $filteredData with the $retrievedData everything would work as expected, but i cant just replace the code base.
setPageSizeandsetCurPagemethods whereas those methods are already being applied in the_applyCollectionModifiersmethod ? – Raphael at Digital Pianism Mar 08 '16 at 11:28Mage::helper('core')->jsonEncode(array_values($products))? Are you able to retrieve a JSON that contains every product ids ? – Raphael at Digital Pianism Mar 09 '16 at 09:27array_values($products)before the return ? – Raphael at Digital Pianism Mar 09 '16 at 11:03json_encoded? According to the answer you linked in your question,stringis a valid return type. – simonthesorcerer Mar 09 '16 at 11:46