I would like to sort a Varien_Object in Magento with a custom attribute.
I got something like this:
$thing_1 = new Varien_Object();
$thing_1->setName('Richard');
$thing_1->setOrder(2);
$thing_2 = new Varien_Object();
$thing_2->setName('Jane');
$thing_2->setOrder(1);
$collection_of_things = new Varien_Data_Collection();
$collection_of_things
->addItem($thing_1)
->addItem($thing_2);
I want to sort it ASC so that Jane can be in front of Richard
Thanks.
Varien_Data_Collection has method for sorting but this method is rendered to SQL query in the execution.
public function setOrder($field, $direction = self::SORT_ORDER_DESC)
if you additems manually it will be added with index in the order you added them so what you need to do it to sort the objects first then add them to the data collection
look at this question Sort array of objects by object fields
Related
I need to use paginate and simplepaginate on a collection, so i'm trying to convert the collection into a builder object.
To do so I am thinking of creating a function that gets the id of every item in the collection and then builds a query with it, but that seemed to me like a lot of resources waisted,
Is there a simpler way ?
A better way to do this is to build paginator object manually using the existing collection.
From the docs:
Sometimes you may wish to create a pagination instance manually, passing it an array of items. You may do so by creating either an Illuminate\Pagination\Paginator or Illuminate\Pagination\LengthAwarePaginator instance, depending on your needs.
The Paginator class does not need to know the total number of items in the result set; however, because of this, the class does not have methods for retrieving the index of the last page. The LengthAwarePaginator accepts almost the same arguments as the Paginator; however, it does require a count of the total number of items in the result set.
In other words, the Paginator corresponds to the simplePaginate method on the query builder and Eloquent, while the LengthAwarePaginator corresponds to the paginate method.
Building on what Alexey said, as alternative, you can build a Paginator from a collection manually. This is a simpler way without the waste of an additional query. e.g.
// Collection $collection
$perPage = 10;
$currentPage = Illuminate\Pagination\Paginator::resolveCurrentPage() ?? 1;
$itemsOnPage = $collection->skip(10 * ($currentPage-1))->take($perPage);
$paginatorPath = Illuminate\Pagination\Paginator::resolveCurrentPath();
$paginator = new \Illuminate\Pagination\LengthAwarePaginator(
$itemsOnPage,
$collection->count(),
$perPage,
$currentPage,
['path' => $paginatorPath]
);
Then in your view,
{!! $paginator->render() !!}
when using the fluid debug array I see a nested array lige this:
building
[+]floor
[+]room
When clicking the + the sub array is expanded sorted by UID and not by the "sorting" as I have specified in my repository.
protected $defaultOrderings = array(
'sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
);
Can I either access the sorting value somehow?
Or can I somehow force TYPO3 to sort its own array after sorting?
The sorting field should not be manually set.
If you want to sort the entries please use the DataHandler like the Typo3 Backend.
Here is a solution:
TYPO3 CommandController: How to set table field "sorting" of Extbase Object?
By "clicking the +", you mean that the subobjects aren't sorted the way you specified in the TCA?
The sorting is lost on the subobjects because Extbases PersistenceRepository by default only sorts by the order specified in the object itself. But thats no biggie, you just have to specify to order by the subproperty, either with the defaultOrderings property or when building the query:
class FloorRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
// Order by BE sorting
protected $defaultOrderings = array(
'sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
'room.sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
);
...
}
This should give you the Rooms of a Floor, Ordered by the sorting of the Floors, and in each Floor, the Rooms sorted by their sorting.
You can access the sorting property by defining it as integer in your model and creating the related getter (setter if needed)
protected $sorting
Does anyone know of a clever way to read sort order array from Magento product collection? There's a protected property _orders in the object. I could reach it over
$collection->getSelect()->getPart('order')
but then I'd have to do string parsing.
I was hoping there was a public method of some sort that would fetch sort order info from product collection?
You can use Reflection :
$property = new ReflectionProperty(get_class($collection), '_orders');
$property->setAccessible(true);
$orders = $property->getValue($collection);
But you won't avoid some string parsing, as order values are stored in strings ($field.' '.Varien_Data_Collection::SORT_ORDER_(ASC|DESC))
For a product collection with toolbar you can ask the toolbar the current sorting order:
Mage::getBlockSingleton('catalog/product_list_toolbar')->getCurrentOrder()
I am trying to show Grouped Products list based on attributes of its associated simple products. Right now i am doing like below
- Create a collection of simple products and add attribute filters like color,brand etc., like below
$productCollection = Mage::getModel('catalog/product')->getCollection()
->addStoreFilter(Mage::app()->getStore())
->addAttributeToFilter($aname,$avalue)
->addAttributeToFilter('type_id', array('eq' => 'simple'))
->addAttributeToFilter(ATTRIBUTE_CODE,ATTRIBUTE_VALUE_ID);
(->addAttributeToFilter('color',5))
- Obtain all resultant ids and get its parent ids using the below
Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($productCollection->getAllIds());
- Read the parent ids from above object and show the result in a custom grid that i created
- Created a paging logic for parent ids and do paging in view file
This logic really consumes more time, is there any way that i can do all these in a single collection? may be inner join sort of method between simple and grouped products!
Please suggest.
Thanks,
Balan
It depends of attributes you want to filter with.
Magento already have prepared data for filtering grouped products by simple product attributes. It is stored in catalog_product_index_eav.
But these attributes should be marked as 'Filterable' in magento admin.
/** #var $productCollection Mage_Catalog_Model_Resource_Product_Collection */
$productCollection = Mage::getModel('catalog/product')->getCollection();
$productCollection->addStoreFilter(Mage::app()->getStore())
->addAttributeToFilter('type_id', 'grouped');
$resource = Mage::getModel('core/resource');
$productCollection->getSelect()
->join(array('filter_eav' => $resource->getTableName('catalog/product_index_eav')),
"e.entity_id = filter_eav.entity_id AND filter_eav.attribute_id = {$attributeId} AND value = {$valueId}",
array(''));
Originally this table is used in Mage_Catalog_Model_Resource_Layer_Filter_Attribute function applyFilterToCollection. But it requires filter object as param.
This might be what you are looking for. It works well.
http://www.commerceextensions.com/filterable-grouped-products.html
I have an array object that is an output of a magento fetchall from DB and i want this to be converted to an object of a Collections class so that i can implement pagination and use this collection to join with other tables. Can you please help me here ? been stuck for a long time now !!
In order to convert an array to a collection object:
1> Create an instance of Varien_Db_Collection
$collection = new Varien_Data_Collection();
2> Create an instance of Varien_Object and set the array data
$rowObj = new Varien_Object();
$rowObj->setData($row);
3> Finally add the Varien_Object to Collection instance
$collection->addItem($rowObj);
4> Now $collection is a collection object.
Magento hasn't a built in conversor for that, but you can write you query using Collections, or load the Collection based on all ids from your array.
Also, populating a collection can be done with the addItem method.
If you have an array of ids $product_ids, you can use:
$collection = Mage::getModel('catalog/product')->getCollection()
->addIdFilter($product_ids);